home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 0.9.1.3 stable / flock-0.9.1.3.en-US.win32.exe / flock / chrome / browser.jar / content / browser / browser.js < prev    next >
Text File  |  2007-08-30  |  241KB  |  6,583 lines

  1. //@line 58 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2.  
  3. const NS_ERROR_MODULE_NETWORK = 2152398848;
  4. const NS_NET_STATUS_READ_FROM = NS_ERROR_MODULE_NETWORK + 8;
  5. const NS_NET_STATUS_WROTE_TO  = NS_ERROR_MODULE_NETWORK + 9;
  6. const kXULNS =
  7.     "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  8.  
  9. //@line 66 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  10. // For Places-enabled builds, this is in
  11. // chrome://browser/content/places/controller.js
  12. var Ci = Components.interfaces;
  13. var Cc = Components.classes;
  14. var Cr = Components.results;
  15. //@line 72 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  16.  
  17. const nsCI               = Components.interfaces;
  18. const nsIWebNavigation   = nsCI.nsIWebNavigation;
  19. const FLOCK_DEFER_DEFAULT_CHECK_PREF = "flock.firstrun.didDelayDefaultPrompt";
  20.  
  21. const MAX_HISTORY_MENU_ITEMS = 15;
  22.  
  23. // bookmark dialog features
  24. //@line 83 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  25. const BROWSER_ADD_BM_FEATURES = "centerscreen,chrome,dialog,resizable,dependent";
  26. //@line 85 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  27.  
  28. const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
  29. const TYPE_XUL = "application/vnd.mozilla.xul+xml";
  30.  
  31. var gBrowserGlue = Components.classes["@mozilla.org/browser/browserglue;1"]
  32.                              .getService(nsCI.nsIBrowserGlue);
  33. var gRDF = null;
  34. var gGlobalHistory = null;
  35. var gURIFixup = null;
  36. var gPageStyleButton = null;
  37. var gCharsetMenu = null;
  38. var gLastBrowserCharset = null;
  39. var gPrevCharset = null;
  40. var gURLBar = null;
  41. var gURLBarContainer = null;
  42. var gProxyButton = null;
  43. var gProxyFavIcon = null;
  44. var gProxyDeck = null;
  45. var gNavigatorBundle = null;
  46. var gIsLoadingBlank = false;
  47. var gLastValidURLStr = "";
  48. var gLastValidURL = null;
  49. var gHaveUpdatedToolbarState = false;
  50. var gClickSelectsAll = false;
  51. var gMustLoadSidebar = false;
  52. var gProgressMeterPanel = null;
  53. var gProgressCollapseTimer = null;
  54. var gPrefService = null;
  55. var appCore = null;
  56. var gBrowser = null;
  57. var gSidebarCommand = "";
  58.  
  59. // Global variable that holds the nsContextMenu instance.
  60. var gContextMenu = null;
  61.  
  62. var gChromeState = null; // chrome state before we went into print preview
  63.  
  64. var gSanitizeListener = null;
  65.  
  66. var gURLBarAutoFillPrefListener = null;
  67. var gAutoHideTabbarPrefListener = null;
  68. var gGoButtonPrefListener = null;
  69.  
  70. //@line 131 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  71.  
  72. /**
  73. * We can avoid adding multiple load event listeners and save some time by adding
  74. * one listener that calls all real handlers.
  75. */
  76.  
  77. function pageShowEventHandlers(event)
  78. {
  79.   // Filter out events that are not about the document load we are interested in
  80.   if (event.originalTarget == content.document) {
  81.     checkForDirectoryListing();
  82.     charsetLoadListener(event);
  83.     
  84.     XULBrowserWindow.asyncUpdateUI();
  85.   }
  86.  
  87.   // some event handlers want to be told what the original browser/listener is
  88.   var targetBrowser = null;
  89.   if (gBrowser.mTabbedMode) {
  90.     var targetBrowserIndex = gBrowser.getBrowserIndexForDocument(event.originalTarget);
  91.     if (targetBrowserIndex == -1)
  92.       return;
  93.     targetBrowser = gBrowser.getBrowserAtIndex(targetBrowserIndex);
  94.   } else {
  95.     targetBrowser = gBrowser.mCurrentBrowser;
  96.   }
  97.  
  98. //@line 159 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  99.   // update the last visited date
  100.   if (targetBrowser.currentURI.spec)
  101.     BMSVC.updateLastVisitedDate(targetBrowser.currentURI.spec,
  102.                                 targetBrowser.contentDocument.characterSet);
  103. //@line 164 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  104. }
  105.  
  106. /**
  107.  * Determine whether or not the content area is displaying a page with frames,
  108.  * and if so, toggle the display of the 'save frame as' menu item.
  109.  **/
  110. function getContentAreaFrameCount()
  111. {
  112.   var saveFrameItem = document.getElementById("menu_saveFrame");
  113.   if (!content || !content.frames.length || !isContentFrame(document.commandDispatcher.focusedWindow))
  114.     saveFrameItem.setAttribute("hidden", "true");
  115.   else
  116.     saveFrameItem.removeAttribute("hidden");
  117. }
  118.  
  119. function UpdateBackForwardButtons()
  120. {
  121.   var backBroadcaster = document.getElementById("Browser:Back");
  122.   var forwardBroadcaster = document.getElementById("Browser:Forward");
  123.  
  124.   var webNavigation = gBrowser.webNavigation;
  125.  
  126.   // Avoid setting attributes on broadcasters if the value hasn't changed!
  127.   // Remember, guys, setting attributes on elements is expensive!  They
  128.   // get inherited into anonymous content, broadcast to other widgets, etc.!
  129.   // Don't do it if the value hasn't changed! - dwh
  130.  
  131.   var backDisabled = backBroadcaster.hasAttribute("disabled");
  132.   var forwardDisabled = forwardBroadcaster.hasAttribute("disabled");
  133.   if (backDisabled == webNavigation.canGoBack) {
  134.     if (backDisabled)
  135.       backBroadcaster.removeAttribute("disabled");
  136.     else
  137.       backBroadcaster.setAttribute("disabled", true);
  138.   }
  139.  
  140.   if (forwardDisabled == webNavigation.canGoForward) {
  141.     if (forwardDisabled)
  142.       forwardBroadcaster.removeAttribute("disabled");
  143.     else
  144.       forwardBroadcaster.setAttribute("disabled", true);
  145.   }
  146. }
  147.  
  148. //@line 283 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  149.  
  150. //@line 285 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  151. function UpdateBookmarkAllTabsMenuitem()
  152. {
  153.   var tabbrowser = getBrowser();
  154.   var numTabs = 0;
  155.   if (tabbrowser)
  156.     numTabs = tabbrowser.tabContainer.childNodes.length;
  157.  
  158.   var bookmarkAllCommand = document.getElementById("Browser:BookmarkAllTabs");
  159.   if (numTabs > 1)
  160.     bookmarkAllCommand.removeAttribute("disabled");
  161.   else
  162.     bookmarkAllCommand.setAttribute("disabled", "true");
  163. }
  164.  
  165. function addBookmarkMenuitems()
  166. {
  167.   var tabbrowser = getBrowser();
  168.   var tabMenu = document.getAnonymousElementByAttribute(tabbrowser,"anonid","tabContextMenu");
  169.   var bookmarkAllTabsItem = document.createElement("menuitem");
  170.   bookmarkAllTabsItem.setAttribute("label", gNavigatorBundle.getString("bookmarkAllTabs_label"));
  171.   bookmarkAllTabsItem.setAttribute("accesskey", gNavigatorBundle.getString("bookmarkAllTabs_accesskey"));
  172.   bookmarkAllTabsItem.setAttribute("command", "Browser:BookmarkAllTabs");
  173.   // set up the bookmarkAllTabs menu item correctly when the menu popup is shown
  174.   tabMenu.addEventListener("popupshowing", UpdateBookmarkAllTabsMenuitem, false);
  175.   var bookmarkCurTabItem = document.createElement("menuitem");
  176.   bookmarkCurTabItem.setAttribute("label", gNavigatorBundle.getString("bookmarkCurTab_label"));
  177.   bookmarkCurTabItem.setAttribute("accesskey", gNavigatorBundle.getString("bookmarkCurTab_accesskey"));
  178.   bookmarkCurTabItem.setAttribute("oncommand", "BookmarkThisTab();");
  179.   var menuseparator = document.createElement("menuseparator");
  180.   var insertPos = tabMenu.lastChild.previousSibling;
  181.   tabMenu.insertBefore(bookmarkAllTabsItem, insertPos);
  182.   tabMenu.insertBefore(bookmarkCurTabItem, bookmarkAllTabsItem);
  183.   tabMenu.insertBefore(menuseparator, bookmarkCurTabItem);
  184. }
  185.  
  186. function BookmarkThisTab()
  187. {
  188.   var tab = getBrowser().mContextTab;
  189.   if (tab.localName != "tab")
  190.     tab = getBrowser().mCurrentTab;
  191.  
  192.   addBookmarkAs(tab.linkedBrowser, false);
  193. }
  194. //@line 329 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  195.  
  196. const gSessionHistoryObserver = {
  197.   observe: function(subject, topic, data)
  198.   {
  199.     if (topic != "browser:purge-session-history")
  200.       return;
  201.  
  202.     var backCommand = document.getElementById("Browser:Back");
  203.     backCommand.setAttribute("disabled", "true");
  204.     var fwdCommand = document.getElementById("Browser:Forward");
  205.     fwdCommand.setAttribute("disabled", "true");
  206.  
  207.     //Clear undo history of all URL Bars
  208.     var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  209.     var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  210.     var windows = windowManagerInterface.getEnumerator("navigator:browser");
  211.     while (windows.hasMoreElements()) {
  212.       var urlBar = windows.getNext().gURLBar;
  213.       if (urlBar) {
  214.         urlBar.editor.enableUndo(false);
  215.         urlBar.editor.enableUndo(true);
  216.       }
  217.     }
  218.   }
  219. };
  220.  
  221. /**
  222.  * Given a starting docshell and a URI to look up, find the docshell the URI
  223.  * is loaded in. 
  224.  * @param   aDocument
  225.  *          A document to find instead of using just a URI - this is more specific. 
  226.  * @param   aDocShell
  227.  *          The doc shell to start at
  228.  * @param   aSoughtURI
  229.  *          The URI that we're looking for
  230.  * @returns The doc shell that the sought URI is loaded in. Can be in 
  231.  *          subframes.
  232.  */
  233. function findChildShell(aDocument, aDocShell, aSoughtURI) {
  234.   aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation);
  235.   aDocShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  236.   var doc = aDocShell.getInterface(Components.interfaces.nsIDOMDocument);
  237.   if ((aDocument && doc == aDocument) || 
  238.       (aSoughtURI && aSoughtURI.spec == aDocShell.currentURI.spec))
  239.     return aDocShell;
  240.  
  241.   var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeNode);
  242.   for (var i = 0; i < node.childCount; ++i) {
  243.     var docShell = node.getChildAt(i);
  244.     docShell = findChildShell(aDocument, docShell, aSoughtURI);
  245.     if (docShell)
  246.       return docShell;
  247.   }
  248.   return null;
  249. }
  250.  
  251. const gPopupBlockerObserver = {
  252.   _reportButton: null,
  253.   _kIPM: Components.interfaces.nsIPermissionManager,
  254.  
  255.   onUpdatePageReport: function ()
  256.   {
  257.     if (!this._reportButton)
  258.       this._reportButton = document.getElementById("page-report-button");
  259.  
  260.     if (gBrowser.selectedBrowser.pageReport) {
  261.       this._reportButton.setAttribute("blocked", "true");
  262.       if (!gPrefService)
  263.         gPrefService = Components.classes["@mozilla.org/preferences-service;1"]
  264.                                  .getService(Components.interfaces.nsIPrefBranch);
  265.       if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) {
  266.         var bundle_browser = document.getElementById("bundle_browser");
  267.         var brandBundle = document.getElementById("bundle_brand");
  268.         var brandShortName = brandBundle.getString("brandShortName");
  269.         var message;
  270.         var popupCount = gBrowser.selectedBrowser.pageReport.length;
  271. //@line 406 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  272.         var popupButtonText = bundle_browser.getString("popupWarningButton");
  273.         var popupButtonAccesskey = bundle_browser.getString("popupWarningButton.accesskey");
  274. //@line 412 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  275.         if (popupCount > 1)
  276.           message = bundle_browser.getFormattedString("popupWarningMultiple", [brandShortName, popupCount]);
  277.         else
  278.           message = bundle_browser.getFormattedString("popupWarning", [brandShortName]);
  279.  
  280.         var notificationBox = gBrowser.getNotificationBox();
  281.         var notification = notificationBox.getNotificationWithValue("popup-blocked");
  282.         if (notification) {
  283.           notification.label = message;
  284.         }
  285.         else {
  286.           var buttons = [{
  287.             label: popupButtonText,
  288.             accessKey: popupButtonAccesskey,
  289.             popup: "blockedPopupOptions",
  290.             callback: null
  291.           }];
  292.  
  293.           const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
  294.           notificationBox.appendNotification(message, "popup-blocked",
  295.                                              "chrome://browser/skin/Info.png",
  296.                                              priority, buttons);
  297.         }
  298.       }
  299.     }
  300.     else
  301.       this._reportButton.removeAttribute("blocked");
  302.   },
  303.  
  304.   toggleAllowPopupsForSite: function (aEvent)
  305.   {
  306.     var currentURI = gBrowser.selectedBrowser.webNavigation.currentURI;
  307.     var pm = Components.classes["@mozilla.org/permissionmanager;1"]
  308.                        .getService(this._kIPM);
  309.     var shouldBlock = aEvent.target.getAttribute("block") == "true";
  310.     var perm = shouldBlock ? this._kIPM.DENY_ACTION : this._kIPM.ALLOW_ACTION;
  311.     pm.add(currentURI, "popup", perm);
  312.  
  313.     gBrowser.getNotificationBox().removeCurrentNotification();
  314.   },
  315.  
  316.   fillPopupList: function (aEvent)
  317.   {
  318.     var bundle_browser = document.getElementById("bundle_browser");
  319.     // XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites
  320.     //          we should really walk the pageReport and create a list of "allow for <host>"
  321.     //          menuitems for the common subset of hosts present in the report, this will
  322.     //          make us frame-safe.
  323.     //
  324.     // XXXjst - Note that when this is fixed to work with multi-framed sites,
  325.     //          also back out the fix for bug 343772 where
  326.     //          nsGlobalWindow::CheckOpenAllow() was changed to also
  327.     //          check if the top window's location is whitelisted.
  328.     var uri = gBrowser.selectedBrowser.webNavigation.currentURI;
  329.     var blockedPopupAllowSite = document.getElementById("blockedPopupAllowSite");
  330.     try {
  331.       blockedPopupAllowSite.removeAttribute("hidden");
  332.  
  333.       var pm = Components.classes["@mozilla.org/permissionmanager;1"]
  334.                         .getService(this._kIPM);
  335.       if (pm.testPermission(uri, "popup") == this._kIPM.ALLOW_ACTION) {
  336.         // Offer an item to block popups for this site, if a whitelist entry exists
  337.         // already for it.
  338.         var blockString = bundle_browser.getFormattedString("popupBlock", [uri.host]);
  339.         blockedPopupAllowSite.setAttribute("label", blockString);
  340.         blockedPopupAllowSite.setAttribute("block", "true");
  341.       }
  342.       else {
  343.         // Offer an item to allow popups for this site
  344.         var allowString = bundle_browser.getFormattedString("popupAllow", [uri.host]);
  345.         blockedPopupAllowSite.setAttribute("label", allowString);
  346.         blockedPopupAllowSite.removeAttribute("block");
  347.       }
  348.     }
  349.     catch (e) {
  350.       blockedPopupAllowSite.setAttribute("hidden", "true");
  351.     }
  352.  
  353.     var item = aEvent.target.lastChild;
  354.     while (item && item.getAttribute("observes") != "blockedPopupsSeparator") {
  355.       var next = item.previousSibling;
  356.       item.parentNode.removeChild(item);
  357.       item = next;
  358.     }
  359.  
  360.     var foundUsablePopupURI = false;
  361.     var pageReport = gBrowser.selectedBrowser.pageReport;
  362.     if (pageReport) {
  363.       for (var i = 0; i < pageReport.length; ++i) {
  364.         var popupURIspec = pageReport[i].popupWindowURI.spec;
  365.  
  366.         // Sometimes the popup URI that we get back from the pageReport
  367.         // isn't useful (for instance, netscape.com's popup URI ends up
  368.         // being "http://www.netscape.com", which isn't really the URI of
  369.         // the popup they're trying to show).  This isn't going to be
  370.         // useful to the user, so we won't create a menu item for it.
  371.         if (popupURIspec == "" || popupURIspec == "about:blank" ||
  372.             popupURIspec == uri.spec)
  373.           continue;
  374.  
  375.         // Because of the short-circuit above, we may end up in a situation
  376.         // in which we don't have any usable popup addresses to show in
  377.         // the menu, and therefore we shouldn't show the separator.  However,
  378.         // since we got past the short-circuit, we must've found at least
  379.         // one usable popup URI and thus we'll turn on the separator later.
  380.         foundUsablePopupURI = true;
  381.  
  382.         var menuitem = document.createElement("menuitem");
  383.         var label = bundle_browser.getFormattedString("popupShowPopupPrefix",
  384.                                                       [popupURIspec]);
  385.         menuitem.setAttribute("label", label);
  386.         menuitem.setAttribute("popupWindowURI", popupURIspec);
  387.         menuitem.setAttribute("popupWindowFeatures", pageReport[i].popupWindowFeatures);
  388.         menuitem.setAttribute("popupWindowName", pageReport[i].popupWindowName);
  389.         menuitem.setAttribute("oncommand", "gPopupBlockerObserver.showBlockedPopup(event);");
  390.         menuitem.requestingWindow = pageReport[i].requestingWindow;
  391.         menuitem.requestingDocument = pageReport[i].requestingDocument;
  392.         aEvent.target.appendChild(menuitem);
  393.       }
  394.     }
  395.  
  396.     // Show or hide the separator, depending on whether we added any
  397.     // showable popup addresses to the menu.
  398.     var blockedPopupsSeparator =
  399.       document.getElementById("blockedPopupsSeparator");
  400.     if (foundUsablePopupURI)
  401.       blockedPopupsSeparator.removeAttribute("hidden");
  402.     else
  403.       blockedPopupsSeparator.setAttribute("hidden", true);
  404.  
  405.     var blockedPopupDontShowMessage = document.getElementById("blockedPopupDontShowMessage");
  406.     var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
  407.     blockedPopupDontShowMessage.setAttribute("checked", !showMessage);
  408.     if (aEvent.target.localName == "popup")
  409.       blockedPopupDontShowMessage.setAttribute("label", bundle_browser.getString("popupWarningDontShowFromMessage"));
  410.     else
  411.       blockedPopupDontShowMessage.setAttribute("label", bundle_browser.getString("popupWarningDontShowFromStatusbar"));
  412.   },
  413.  
  414.   showBlockedPopup: function (aEvent)
  415.   {
  416.     var target = aEvent.target;
  417.     var popupWindowURI = target.getAttribute("popupWindowURI");
  418.     var features = target.getAttribute("popupWindowFeatures");
  419.     var name = target.getAttribute("popupWindowName");
  420.  
  421.     var dwi = target.requestingWindow;
  422.  
  423.     // If we have a requesting window and the requesting document is
  424.     // still the current document, open the popup.
  425.     if (dwi && dwi.document == target.requestingDocument) {
  426.       dwi.open(popupWindowURI, name, features);
  427.     }
  428.   },
  429.  
  430.   editPopupSettings: function ()
  431.   {
  432.     var host = "";
  433.     try {
  434.       var uri = gBrowser.selectedBrowser.webNavigation.currentURI;
  435.       host = uri.host;
  436.     }
  437.     catch (e) { }
  438.  
  439.     var bundlePreferences = document.getElementById("bundle_preferences");
  440.     var params = { blockVisible   : false,
  441.                    sessionVisible : false,
  442.                    allowVisible   : true,
  443.                    prefilledHost  : host,
  444.                    permissionType : "popup",
  445.                    windowTitle    : bundlePreferences.getString("popuppermissionstitle"),
  446.                    introText      : bundlePreferences.getString("popuppermissionstext") };
  447.     var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  448.                         .getService(Components.interfaces.nsIWindowMediator);
  449.     var existingWindow = wm.getMostRecentWindow("Browser:Permissions");
  450.     if (existingWindow) {
  451.       existingWindow.initWithParams(params);
  452.       existingWindow.focus();
  453.     }
  454.     else
  455.       window.openDialog("chrome://browser/content/preferences/permissions.xul",
  456.                         "_blank", "resizable,dialog=no,centerscreen", params);
  457.   },
  458.  
  459.   dontShowMessage: function ()
  460.   {
  461.     var showMessage = gPrefService.getBoolPref("privacy.popups.showBrowserMessage");
  462.     var firstTime = gPrefService.getBoolPref("privacy.popups.firstTime");
  463.  
  464.     // If the info message is showing at the top of the window, and the user has never
  465.     // hidden the message before, show an info box telling the user where the info
  466.     // will be displayed.
  467.     if (showMessage && firstTime)
  468.       this._displayPageReportFirstTime();
  469.  
  470.     gPrefService.setBoolPref("privacy.popups.showBrowserMessage", !showMessage);
  471.  
  472.     gBrowser.getNotificationBox().removeCurrentNotification();
  473.   },
  474.  
  475.   _displayPageReportFirstTime: function ()
  476.   {
  477.     window.openDialog("chrome://browser/content/pageReportFirstTime.xul", "_blank",
  478.                       "dependent");
  479.   }
  480. };
  481.  
  482. const gXPInstallObserver = {
  483.   _findChildShell: function (aDocShell, aSoughtShell)
  484.   {
  485.     if (aDocShell == aSoughtShell)
  486.       return aDocShell;
  487.  
  488.     var node = aDocShell.QueryInterface(Components.interfaces.nsIDocShellTreeNode);
  489.     for (var i = 0; i < node.childCount; ++i) {
  490.       var docShell = node.getChildAt(i);
  491.       docShell = this._findChildShell(docShell, aSoughtShell);
  492.       if (docShell == aSoughtShell)
  493.         return docShell;
  494.     }
  495.     return null;
  496.   },
  497.  
  498.   _getBrowser: function (aDocShell)
  499.   {
  500.     var tabbrowser = getBrowser();
  501.     for (var i = 0; i < tabbrowser.browsers.length; ++i) {
  502.       var browser = tabbrowser.getBrowserAtIndex(i);
  503.       if (this._findChildShell(browser.docShell, aDocShell))
  504.         return browser;
  505.     }
  506.     return null;
  507.   },
  508.  
  509.   observe: function (aSubject, aTopic, aData)
  510.   {
  511.     var brandBundle = document.getElementById("bundle_brand");
  512.     var browserBundle = document.getElementById("bundle_browser");
  513.     var browser, webNav, wm;
  514.     switch (aTopic) {
  515.     case "xpinstall-install-blocked":
  516.       var shell = aSubject.QueryInterface(Components.interfaces.nsIDocShell);
  517.       browser = this._getBrowser(shell);
  518.       if (browser) {
  519.         var host = browser.docShell.QueryInterface(Components.interfaces.nsIWebNavigation).currentURI.host;
  520.         var brandShortName = brandBundle.getString("brandShortName");
  521.         var notificationName, messageString, buttons;
  522.         if (!gPrefService.getBoolPref("xpinstall.enabled")) {
  523.           notificationName = "xpinstall-disabled"
  524.           if (gPrefService.prefIsLocked("xpinstall.enabled")) {
  525.             messageString = browserBundle.getString("xpinstallDisabledMessageLocked");
  526.             buttons = [];
  527.           }
  528.           else {
  529.             messageString = browserBundle.getFormattedString("xpinstallDisabledMessage",
  530.                                                              [brandShortName, host]);
  531.  
  532.             buttons = [{
  533.               label: browserBundle.getString("xpinstallDisabledButton"),
  534.               accessKey: browserBundle.getString("xpinstallDisabledButton.accesskey"),
  535.               popup: null,
  536.               callback: function editPrefs() {
  537.                 gPrefService.setBoolPref("xpinstall.enabled", true);
  538.                 return false;
  539.               }
  540.             }];
  541.           }
  542.         }
  543.         else {
  544.           // XXXben - use regular software install warnings for now until we can
  545.           // properly differentiate themes. It's likely in fact that themes won't
  546.           // be blocked so this code path will only be reached for extensions.
  547.           notificationName = "xpinstall"
  548.           messageString = browserBundle.getFormattedString("xpinstallPromptWarning",
  549.                                                            [brandShortName, host]);
  550.  
  551.           buttons = [{
  552.             label: browserBundle.getString("xpinstallPromptWarningButton"),
  553.             accessKey: browserBundle.getString("xpinstallPromptWarningButton.accesskey"),
  554.             popup: null,
  555.             callback: function() { return xpinstallEditPermissions(shell); }
  556.           }];
  557.         }
  558.  
  559.         var notificationBox = gBrowser.getNotificationBox(browser);
  560.         if (!notificationBox.getNotificationWithValue(notificationName)) {
  561.           const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
  562.           const iconURL = "chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
  563.           notificationBox.appendNotification(messageString, notificationName,
  564.                                              iconURL, priority, buttons);
  565.         }
  566.       }
  567.       break;
  568.     }
  569.   }
  570. };
  571.  
  572. function xpinstallEditPermissions(aDocShell)
  573. {
  574.   var browser = gXPInstallObserver._getBrowser(aDocShell);
  575.   if (browser) {
  576.     var bundlePreferences = document.getElementById("bundle_preferences");
  577.     var webNav = aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation);
  578.     var params = { blockVisible   : false,
  579.                    sessionVisible : false,
  580.                    allowVisible   : true,
  581.                    prefilledHost  : webNav.currentURI.host,
  582.                    permissionType : "install",
  583.                    windowTitle    : bundlePreferences.getString("addons_permissions_title"),
  584.                    introText      : bundlePreferences.getString("addonspermissionstext") };
  585.     wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  586.                    .getService(Components.interfaces.nsIWindowMediator);
  587.     var existingWindow = wm.getMostRecentWindow("Browser:Permissions");
  588.     if (existingWindow) {
  589.       existingWindow.initWithParams(params);
  590.       existingWindow.focus();
  591.     }
  592.     else
  593.       window.openDialog("chrome://browser/content/preferences/permissions.xul",
  594.                         "_blank", "resizable,dialog=no,centerscreen", params);
  595.     return false;
  596.   }
  597.  
  598.   return true;
  599. }
  600.  
  601. var gProfiler = null;
  602. function BrowserStartup()
  603. {
  604.   // Close the splash screen if it exists
  605.   var nativeApp = Components.classes["@mozilla.org/toolkit/native-app-support;1"]
  606.                 .getService(Components.interfaces.nsINativeAppSupport);
  607.   nativeApp.closeSplashScreen();
  608.   
  609.   gProfiler = Components.classes["@flock.com/profiler;1"]
  610.                 .getService(Components.interfaces.flockIProfiler);
  611.   var bsEvent = gProfiler.profileEventStart("BrowserStartup");
  612.  
  613.   gBrowser = document.getElementById("content");
  614.  
  615.   window.tryToClose = WindowIsClosing;
  616.  
  617.   var uriToLoad = null;
  618.   // Check for window.arguments[0]. If present, use that for uriToLoad.
  619.   if ("arguments" in window && window.arguments[0])
  620.     uriToLoad = window.arguments[0];
  621.  
  622.   gIsLoadingBlank = uriToLoad == "about:blank";
  623.  
  624.   if (!gIsLoadingBlank)
  625.     prepareForStartup();
  626.  
  627. //@line 768 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  628.   if (uriToLoad && !gIsLoadingBlank) {
  629.     if (window.arguments.length >= 3)
  630.       loadURI(uriToLoad, window.arguments[2], window.arguments[3] || null,
  631.               window.arguments[4] || false);
  632.  
  633.     else
  634.       loadOneOrMoreURIs(uriToLoad);
  635.   }
  636. //@line 777 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  637.  
  638.   var sidebarSplitter;
  639.   if (window.opener && !window.opener.closed) {
  640.     if (window.opener.gFindBar && window.opener.gFindBar.mFindMode == FIND_NORMAL) {
  641.       var openerFindBar = window.opener.document.getElementById("FindToolbar");
  642.       if (openerFindBar && !openerFindBar.hidden)
  643.         gFindBar.openFindBar();
  644.     }
  645.  
  646.     var openerSidebarBox = window.opener.document.getElementById("sidebar-box");
  647.     // The opener can be the hidden window too, if we're coming from the state
  648.     // where no windows are open, and the hidden window has no sidebar box.
  649.     if (openerSidebarBox && !openerSidebarBox.hidden && openerSidebarBox.getAttribute("sidebarcommand") != "flock_NewsSidebarBroadcaster") {
  650.       var sidebarBox = document.getElementById("sidebar-box");
  651.       var sidebarTitle = document.getElementById("sidebar-title");
  652.       sidebarTitle.setAttribute("value", window.opener.document.getElementById("sidebar-title").getAttribute("value"));
  653.       sidebarBox.setAttribute("width", openerSidebarBox.boxObject.width);
  654.       var sidebarCmd = openerSidebarBox.getAttribute("sidebarcommand");
  655.       sidebarBox.setAttribute("sidebarcommand", sidebarCmd);
  656.       sidebarBox.setAttribute("src", window.opener.document.getElementById("sidebar").getAttribute("src"));
  657.       gMustLoadSidebar = true;
  658.       sidebarBox.hidden = false;
  659.       sidebarSplitter = document.getElementById("sidebar-splitter");
  660.       sidebarSplitter.hidden = false;
  661.       document.getElementById(sidebarCmd).setAttribute("checked", "true");
  662.     }
  663.   }
  664.   else {
  665.     var box = document.getElementById("sidebar-box");
  666.     if (box.hasAttribute("sidebarcommand") && box.getAttribute("sidebarcommand") != "flock_NewsSidebarBroadcaster") {
  667.       var commandID = box.getAttribute("sidebarcommand");
  668.       if (commandID) {
  669.         var command = document.getElementById(commandID);
  670.         if (command) {
  671.           gMustLoadSidebar = true;
  672.           box.hidden = false;
  673.           sidebarSplitter = document.getElementById("sidebar-splitter");
  674.           sidebarSplitter.hidden = false;
  675.           command.setAttribute("checked", "true");
  676.         }
  677.         else {
  678.           // Remove the |sidebarcommand| attribute, because the element it 
  679.           // refers to no longer exists, so we should assume this sidebar
  680.           // panel has been uninstalled. (249883)
  681.           box.removeAttribute("sidebarcommand");
  682.         }
  683.       }
  684.     }
  685.   }
  686.  
  687.   // Certain kinds of automigration rely on this notification to complete their
  688.   // tasks BEFORE the browser window is shown.
  689.   var obs = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  690.   obs.notifyObservers(null, "browser-window-before-show", "");
  691.  
  692.   // Set a sane starting width/height for all resolutions on new profiles.
  693.   if (!document.documentElement.hasAttribute("width")) {
  694.     var defaultWidth = 994, defaultHeight;
  695.     if (screen.availHeight <= 600) {
  696.       document.documentElement.setAttribute("sizemode", "maximized");
  697.       defaultWidth = 610;
  698.       defaultHeight = 450;
  699.     }
  700.     else {
  701.       // Create a narrower window for large or wide-aspect displays, to suggest
  702.       // side-by-side page view.
  703.       if ((screen.availWidth / 2) >= 800)
  704.         defaultWidth = (screen.availWidth / 2) - 20;
  705.       defaultHeight = screen.availHeight - 10;
  706. //@line 861 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  707.     }
  708.     document.documentElement.setAttribute("width", defaultWidth);
  709.     document.documentElement.setAttribute("height", defaultHeight);
  710.   }
  711.    
  712.   setTimeout(delayedStartup, 0);
  713.  
  714.   gProfiler.profileEventEnd(bsEvent, "");
  715. }
  716.  
  717. function prepareForStartup()
  718. {
  719.   gURLBar = document.getElementById("urlbar");
  720.   gURLBarContainer = document.getElementById("urlbar-container");
  721.   gNavigatorBundle = document.getElementById("bundle_browser");
  722.   gProgressMeterPanel = document.getElementById("statusbar-progresspanel");
  723.   gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver.onUpdatePageReport, false);
  724.   gBrowser.addEventListener("PluginNotFound", gMissingPluginInstaller.newMissingPlugin, true);
  725.   gBrowser.addEventListener("NewTab", BrowserOpenTab, false);
  726.   gBrowser.addEventListener("DOMContentLoaded", FlockDocumentReady, false);
  727.  
  728.   var webNavigation;
  729.   try {
  730.     // Create the browser instance component.
  731.     appCore = Components.classes["@mozilla.org/appshell/component/browser/instance;1"]
  732.                         .createInstance(Components.interfaces.nsIBrowserInstance);
  733.     if (!appCore)
  734.       throw "couldn't create a browser instance";
  735.  
  736.     webNavigation = getWebNavigation();
  737.     if (!webNavigation)
  738.       throw "no XBL binding for browser";
  739.   } catch (e) {
  740.     alert("Error launching browser window:" + e);
  741.     window.close(); // Give up.
  742.     return;
  743.   }
  744.  
  745.   // initialize observers and listeners
  746.   // and give C++ access to gBrowser
  747.   window.XULBrowserWindow = new nsBrowserStatusHandler();
  748.   window.QueryInterface(nsCI.nsIInterfaceRequestor)
  749.         .getInterface(nsIWebNavigation)
  750.         .QueryInterface(nsCI.nsIDocShellTreeItem).treeOwner
  751.         .QueryInterface(nsCI.nsIInterfaceRequestor)
  752.         .getInterface(nsCI.nsIXULWindow)
  753.         .XULBrowserWindow = window.XULBrowserWindow;
  754.   window.QueryInterface(nsCI.nsIDOMChromeWindow).browserDOMWindow =
  755.     new nsBrowserAccess();
  756.  
  757.   // set default character set if provided
  758.   if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
  759.     if (window.arguments[1].indexOf("charset=") != -1) {
  760.       var arrayArgComponents = window.arguments[1].split("=");
  761.       if (arrayArgComponents) {
  762.         //we should "inherit" the charset menu setting in a new window
  763.         getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
  764.       }
  765.     }
  766.   }
  767.  
  768.   // Initialize browser instance..
  769.   appCore.setWebShellWindow(window);
  770.  
  771.   // Manually hook up session and global history for the first browser
  772.   // so that we don't have to load global history before bringing up a
  773.   // window.
  774.   // Wire up session and global history before any possible
  775.   // progress notifications for back/forward button updating
  776.   webNavigation.sessionHistory = Components.classes["@mozilla.org/browser/shistory;1"]
  777.                                            .createInstance(Components.interfaces.nsISHistory);
  778.   var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  779.   os.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
  780.  
  781.   // remove the disablehistory attribute so the browser cleans up, as
  782.   // though it had done this work itself
  783.   gBrowser.browsers[0].removeAttribute("disablehistory");
  784.  
  785.   // enable global history
  786.   gBrowser.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = true;
  787.  
  788.   // hook up UI through progress listener
  789.   gBrowser.addProgressListener(window.XULBrowserWindow, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  790.  
  791.   // Initialize the feedhandler
  792.   FeedHandler.init();
  793.  
  794.   // Initialize the searchbar
  795.   BrowserSearch.init();
  796. }
  797.  
  798. function delayedStartup()
  799. {
  800.   var dsEvent = gProfiler.profileEventStart("delayedStartup");
  801.  
  802.   var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  803.   os.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
  804.   os.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
  805.  
  806.   if (!gPrefService)
  807.     gPrefService = Components.classes["@mozilla.org/preferences-service;1"]
  808.                              .getService(Components.interfaces.nsIPrefBranch);
  809.   BrowserOffline.init();
  810.   
  811.   if (gURLBar && document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1) {
  812.     gURLBar.setAttribute("readonly", "true");
  813.     gURLBar.setAttribute("enablehistory", "false");
  814.   }
  815.  
  816.   if (gIsLoadingBlank)
  817.     prepareForStartup();
  818.  
  819.   if (gURLBar)
  820.     gURLBar.addEventListener("dragdrop", URLBarOnDrop, true);
  821.  
  822.   gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
  823.  
  824.   window.addEventListener("keypress", ctrlNumberTabSelection, false);
  825.  
  826.   if (gMustLoadSidebar) {
  827.     var sidebar = document.getElementById("sidebar");
  828.     var sidebarBox = document.getElementById("sidebar-box");
  829.     sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
  830.   }
  831.  
  832.   gFindBar.initFindBar();
  833.  
  834. //@line 989 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  835.   // add bookmark options to context menu for tabs
  836.   addBookmarkMenuitems();
  837.   initServices();
  838.   initBMService();
  839.   // now load bookmarks
  840.   BMSVC.readBookmarks();
  841.   var bt = document.getElementById("bookmarks-ptf");
  842.   if (bt) {
  843.     var btf = BMSVC.getBookmarksToolbarFolder().Value;
  844.     bt.ref = btf;
  845.     document.getElementById("bookmarks-chevron").ref = btf;
  846.     bt.database.AddObserver(BookmarksToolbarRDFObserver);
  847.   }
  848.   window.addEventListener("resize", BookmarksToolbar.resizeFunc, false);
  849.   document.getElementById("PersonalToolbar")
  850.           .controllers.appendController(BookmarksMenuController);
  851. //@line 1013 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  852.  
  853.   // called when we go into full screen, even if it is
  854.   // initiated by a web page script
  855.   window.addEventListener("fullscreen", onFullScreen, true);
  856.  
  857.   var element;
  858.   if (gIsLoadingBlank && gURLBar && !gURLBar.hidden &&
  859.       !gURLBarContainer.parentNode.collapsed)
  860.     element = gURLBar;
  861.   else
  862.     element = content;
  863.  
  864.   // This is a redo of the fix for jag bug 91884
  865.   var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  866.                      .getService(Components.interfaces.nsIWindowWatcher);
  867.   if (window == ww.activeWindow) {
  868.     element.focus();
  869.   } else {
  870.     // set the element in command dispatcher so focus will restore properly
  871.     // when the window does become active
  872.     if (element instanceof Components.interfaces.nsIDOMWindow) {
  873.       document.commandDispatcher.focusedWindow = element;
  874.       document.commandDispatcher.focusedElement = null;
  875.     } else if (element instanceof Components.interfaces.nsIDOMElement) {
  876.       document.commandDispatcher.focusedWindow = element.ownerDocument.defaultView;
  877.       document.commandDispatcher.focusedElement = element;
  878.     }
  879.   }
  880.  
  881.   SetPageProxyState("invalid");
  882.  
  883.   var toolbox = document.getElementById("navigator-toolbox");
  884.   toolbox.customizeDone = BrowserToolboxCustomizeDone;
  885.  
  886.   // Set up Sanitize Item
  887.   gSanitizeListener = new SanitizeListener();
  888.  
  889.   var pbi = gPrefService.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  890.  
  891.   // Enable/Disable URL Bar Auto Fill
  892.   gURLBarAutoFillPrefListener = new URLBarAutoFillPrefListener();
  893.   pbi.addObserver(gURLBarAutoFillPrefListener.domain, gURLBarAutoFillPrefListener, false);
  894.  
  895.   // Enable/Disable auto-hide tabbar
  896.   gAutoHideTabbarPrefListener = new AutoHideTabbarPrefListener();
  897.   pbi.addObserver(gAutoHideTabbarPrefListener.domain, gAutoHideTabbarPrefListener, false);
  898.  
  899.   // Enable/Disable Go button
  900.   gGoButtonPrefListener = new GoButtonPrefListener();
  901.   pbi.addObserver(gGoButtonPrefListener.domain, gGoButtonPrefListener, false);
  902.  
  903.   pbi.addObserver(gHomeButton.prefDomain, gHomeButton, false);
  904.   gHomeButton.updateTooltip();
  905.  
  906.   gClickSelectsAll = gPrefService.getBoolPref("browser.urlbar.clickSelectsAll");
  907.   if (gURLBar)
  908.     gURLBar.clickSelectsAll = gClickSelectsAll;
  909.  
  910. //@line 1072 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  911.   // Perform default browser checking (after window opens).
  912.   var shell = getShellService();
  913.   if (shell) {
  914.     var shouldCheck = shell.shouldCheckDefaultBrowser;
  915.     var willRestoreSession = false;
  916.     try {
  917.       var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
  918.                getService(Ci.nsISessionStartup);
  919.       willRestoreSession = ss.doRestore();
  920.     }
  921.     catch (ex) { /* never mind; suppose SessionStore is broken */ }
  922.     if (shouldCheck && !shell.isDefaultBrowser(true) && !willRestoreSession) {
  923.       if (gPrefService.getPrefType(FLOCK_DEFER_DEFAULT_CHECK_PREF) &&
  924.           gPrefService.getBoolPref(FLOCK_DEFER_DEFAULT_CHECK_PREF)) {
  925.         shouldCheck = (shouldCheck && true);
  926.       } else {
  927.         shouldCheck = true;
  928.         // JMC - Gonna do this on browser shutdown instead
  929.       }
  930.       var brandBundle = document.getElementById("bundle_brand");
  931.       var shellBundle = document.getElementById("bundle_shell");
  932.  
  933.       var brandShortName = brandBundle.getString("brandShortName");
  934.       var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
  935.       var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
  936.                                                          [brandShortName]);
  937.       var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
  938.                                                          [brandShortName]);
  939.       const IPS = Components.interfaces.nsIPromptService;
  940.       var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  941.                                                 .getService(IPS);
  942.       var checkEveryTime = { value: shouldCheck };
  943.       var rv = ps.confirmEx(window, promptTitle, promptMessage,
  944.                             (IPS.BUTTON_TITLE_YES * IPS.BUTTON_POS_0) +
  945.                             (IPS.BUTTON_TITLE_NO * IPS.BUTTON_POS_1),
  946.                             null, null, null, checkboxLabel, checkEveryTime);
  947.       if (rv == 0)
  948.         shell.setDefaultBrowser(true, false);
  949.       shell.shouldCheckDefaultBrowser = checkEveryTime.value;
  950.     }
  951.   }
  952. //@line 1114 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  953.  
  954.   // BiDi UI
  955.   gBidiUI = isBidiEnabled();
  956.   if (gBidiUI) {
  957.     document.getElementById("documentDirection-separator").hidden = false;
  958.     document.getElementById("documentDirection-swap").hidden = false;
  959.     document.getElementById("textfieldDirection-separator").hidden = false;
  960.     document.getElementById("textfieldDirection-swap").hidden = false;
  961.   }
  962.  
  963. //@line 1130 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  964.  
  965.   // Initialize the microsummary service by retrieving it, prompting its factory
  966.   // to create its singleton, whose constructor initializes the service.
  967.   Cc["@mozilla.org/microsummary/service;1"].getService(Ci.nsIMicrosummaryService);
  968.  
  969.   // initialize the session-restore service (in case it's not already running)
  970.   if (document.documentElement.getAttribute("windowtype") == "navigator:browser") {
  971.     try {
  972.       var ss = Cc["@mozilla.org/browser/sessionstore;1"].
  973.                getService(Ci.nsISessionStore);
  974.       ss.init(window);
  975.     } catch(ex) {
  976.       dump("nsSessionStore could not be initialized: " + ex + "\n");
  977.     }
  978.   }
  979.  
  980.   // browser-specific tab augmentation
  981.   AugmentTabs.init();
  982.  
  983.   gProfiler.profileEventEnd(dsEvent, "");
  984. }
  985.  
  986. function BrowserShutdown()
  987. {
  988.   var os = Components.classes["@mozilla.org/observer-service;1"]
  989.     .getService(Components.interfaces.nsIObserverService);
  990.   os.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
  991.   os.removeObserver(gXPInstallObserver, "xpinstall-install-blocked");
  992.  
  993.   try {
  994.     gBrowser.removeProgressListener(window.XULBrowserWindow);
  995.   } catch (ex) {
  996.   }
  997.  
  998. //@line 1165 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  999.   try {
  1000.     document.getElementById("PersonalToolbar")
  1001.             .controllers.removeController(BookmarksMenuController);
  1002.   } catch (ex) {
  1003.   }
  1004.  
  1005.   var bt = document.getElementById("bookmarks-ptf");
  1006.   if (bt) {
  1007.     try {
  1008.       bt.database.RemoveObserver(BookmarksToolbarRDFObserver);
  1009.     } catch (ex) {
  1010.     }
  1011.   }
  1012. //@line 1179 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1013.  
  1014.   try {
  1015.     var pbi = gPrefService.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  1016.     pbi.removeObserver(gURLBarAutoFillPrefListener.domain, gURLBarAutoFillPrefListener);
  1017.     pbi.removeObserver(gAutoHideTabbarPrefListener.domain, gAutoHideTabbarPrefListener);
  1018.     pbi.removeObserver(gGoButtonPrefListener.domain, gGoButtonPrefListener);
  1019.     pbi.removeObserver(gHomeButton.prefDomain, gHomeButton);
  1020.   } catch (ex) {
  1021.   }
  1022.  
  1023.   if (gSanitizeListener)
  1024.     gSanitizeListener.shutdown();
  1025.  
  1026.   BrowserOffline.uninit();
  1027.  
  1028.   gFindBar.uninitFindBar();
  1029.  
  1030.   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  1031.   var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  1032.   var enumerator = windowManagerInterface.getEnumerator(null);
  1033.   enumerator.getNext();
  1034.   if (!enumerator.hasMoreElements()) {
  1035.     document.persist("sidebar-box", "sidebarcommand");
  1036.     document.persist("sidebar-box", "width");
  1037.     document.persist("sidebar-box", "src");
  1038.     document.persist("sidebar-title", "value");
  1039.     // if this is the last browser window, make sure the firstrun deferred pref is set
  1040.     gPrefService.setBoolPref(FLOCK_DEFER_DEFAULT_CHECK_PREF, true);
  1041.   }
  1042.  
  1043.   window.XULBrowserWindow.destroy();
  1044.   window.XULBrowserWindow = null;
  1045.   window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  1046.         .getInterface(Components.interfaces.nsIWebNavigation)
  1047.         .QueryInterface(Components.interfaces.nsIDocShellTreeItem).treeOwner
  1048.         .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  1049.         .getInterface(Components.interfaces.nsIXULWindow)
  1050.         .XULBrowserWindow = null;
  1051.   window.QueryInterface(nsCI.nsIDOMChromeWindow).browserDOMWindow = null;
  1052.  
  1053.   // Close the app core.
  1054.   if (appCore)
  1055.     appCore.close();
  1056. }
  1057.  
  1058. //@line 1286 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1059.  
  1060. function URLBarAutoFillPrefListener()
  1061. {
  1062.   this.toggleAutoFillInURLBar();
  1063. }
  1064.  
  1065. URLBarAutoFillPrefListener.prototype =
  1066. {
  1067.   domain: "browser.urlbar.autoFill",
  1068.   observe: function (aSubject, aTopic, aPrefName)
  1069.   {
  1070.     if (aTopic != "nsPref:changed" || aPrefName != this.domain)
  1071.       return;
  1072.  
  1073.     this.toggleAutoFillInURLBar();
  1074.   },
  1075.  
  1076.   toggleAutoFillInURLBar: function ()
  1077.   {
  1078.     if (!gURLBar)
  1079.       return;
  1080.  
  1081.     var prefValue = false;
  1082.     try {
  1083.       prefValue = gPrefService.getBoolPref(this.domain);
  1084.     }
  1085.     catch (e) {
  1086.     }
  1087.  
  1088.     if (prefValue)
  1089.       gURLBar.setAttribute("completedefaultindex", "true");
  1090.     else
  1091.       gURLBar.removeAttribute("completedefaultindex");
  1092.   }
  1093. }
  1094.  
  1095. function AutoHideTabbarPrefListener()
  1096. {
  1097.   this.toggleAutoHideTabbar();
  1098. }
  1099.  
  1100. AutoHideTabbarPrefListener.prototype =
  1101. {
  1102.   domain: "browser.tabs.autoHide",
  1103.   observe: function (aSubject, aTopic, aPrefName)
  1104.   {
  1105.     if (aTopic != "nsPref:changed" || aPrefName != this.domain)
  1106.       return;
  1107.  
  1108.     this.toggleAutoHideTabbar();
  1109.   },
  1110.  
  1111.   toggleAutoHideTabbar: function ()
  1112.   {
  1113.     if (gBrowser.tabContainer.childNodes.length == 1 &&
  1114.         window.toolbar.visible) {
  1115.       var aVisible = false;
  1116.       try {
  1117.         aVisible = !gPrefService.getBoolPref(this.domain);
  1118.       }
  1119.       catch (e) {
  1120.       }
  1121.       gBrowser.setStripVisibilityTo(aVisible);
  1122.       gPrefService.setBoolPref("browser.tabs.forceHide", false);
  1123.     }
  1124.   }
  1125. }
  1126.  
  1127. function GoButtonPrefListener()
  1128. {
  1129.   this.toggleGoButton();
  1130. }
  1131.  
  1132. GoButtonPrefListener.prototype =
  1133. {
  1134.   domain: "browser.urlbar.hideGoButton",
  1135.   observe: function (aSubject, aTopic, aPrefName)
  1136.   {
  1137.     if (aTopic != "nsPref:changed" || aPrefName != this.domain)
  1138.       return;
  1139.  
  1140.     this.toggleGoButton();
  1141.   },
  1142.  
  1143.   toggleGoButton: function ()
  1144.   {
  1145.     var aHide = false;
  1146.     try {
  1147.       aHide = gPrefService.getBoolPref(this.domain);
  1148.     }
  1149.     catch (e) {
  1150.     }
  1151.     document.getElementById("go-button-stack").hidden = aHide;
  1152.   }
  1153. }
  1154.  
  1155. function SanitizeListener()
  1156. {
  1157.   var pbi = gPrefService.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  1158.   pbi.addObserver(this.promptDomain, this, false);
  1159.  
  1160.   this._defaultLabel = document.getElementById("sanitizeItem")
  1161.                                .getAttribute("label");
  1162.   this._updateSanitizeItem();
  1163.  
  1164.   if (gPrefService.prefHasUserValue(this.didSanitizeDomain)) {
  1165.     gPrefService.clearUserPref(this.didSanitizeDomain);
  1166.     // We need to persist this preference change, since we want to
  1167.     // check it at next app start even if the browser exits abruptly
  1168.     gPrefService.savePrefFile(null);
  1169.   }
  1170. }
  1171.  
  1172. SanitizeListener.prototype =
  1173. {
  1174.   promptDomain      : "privacy.sanitize.promptOnSanitize",
  1175.   didSanitizeDomain : "privacy.sanitize.didShutdownSanitize",
  1176.  
  1177.   observe: function (aSubject, aTopic, aPrefName)
  1178.   {
  1179.     this._updateSanitizeItem();
  1180.   },
  1181.  
  1182.   shutdown: function ()
  1183.   {
  1184.     var pbi = gPrefService.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  1185.     pbi.removeObserver(this.promptDomain, this);
  1186.   },
  1187.  
  1188.   _updateSanitizeItem: function ()
  1189.   {
  1190.     var label = gPrefService.getBoolPref(this.promptDomain) ?
  1191.         gNavigatorBundle.getString("sanitizeWithPromptLabel") : 
  1192.         this._defaultLabel;
  1193.     document.getElementById("sanitizeItem").setAttribute("label", label);
  1194.   }
  1195. }
  1196.  
  1197. function ctrlNumberTabSelection(event)
  1198. {
  1199.   if (event.altKey && event.keyCode == KeyEvent.DOM_VK_RETURN) {
  1200.     // XXXblake Proper fix is to just check whether focus is in the urlbar. However, focus with the autocomplete widget is all
  1201.     // hacky and broken and there's no way to do that right now. So this just patches it to ensure that alt+enter works when focus
  1202.     // is on a link.
  1203.     if (!(document.commandDispatcher.focusedElement instanceof HTMLAnchorElement)) {
  1204.       // Don't let winxp beep on ALT+ENTER, since the URL bar uses it.
  1205.       event.preventDefault();
  1206.       return;
  1207.     }
  1208.   }
  1209.  
  1210. //@line 1444 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1211.   if (!event.ctrlKey)
  1212. //@line 1447 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1213.     return;
  1214.  
  1215.   // \d in a RegExp will find any Unicode character with the "decimal digit"
  1216.   // property (Nd)
  1217.   var regExp = /\d/;
  1218.   if (!regExp.test(String.fromCharCode(event.charCode)))
  1219.     return;
  1220.  
  1221.   // Some Unicode decimal digits are in the range U+xxx0 - U+xxx9 and some are
  1222.   // in the range U+xxx6 - U+xxxF. Find the digit 1 corresponding to our
  1223.   // character.
  1224.   var digit1 = (event.charCode & 0xFFF0) | 1;
  1225.   if (!regExp.test(String.fromCharCode(digit1)))
  1226.     digit1 += 6;
  1227.  
  1228.   var index = event.charCode - digit1;
  1229.   if (index < 0)
  1230.     return;
  1231.  
  1232.   // [Ctrl]+[9] always selects the last tab
  1233.   if (index == 8)
  1234.     index = gBrowser.tabContainer.childNodes.length - 1;
  1235.   else if (index >= gBrowser.tabContainer.childNodes.length)
  1236.     return;
  1237.  
  1238.   var oldTab = gBrowser.selectedTab;
  1239.   var newTab = gBrowser.tabContainer.childNodes[index];
  1240.   if (newTab != oldTab) {
  1241.     oldTab.selected = false;
  1242.     gBrowser.selectedTab = newTab;
  1243.   }
  1244.  
  1245.   event.preventDefault();
  1246.   event.stopPropagation();
  1247. }
  1248.  
  1249. function gotoHistoryIndex(aEvent)
  1250. {
  1251.   var index = aEvent.target.getAttribute("index");
  1252.   if (!index)
  1253.     return false;
  1254.  
  1255.   var where = whereToOpenLink(aEvent);
  1256.  
  1257.   if (where == "current") {
  1258.     // Normal click.  Go there in the current tab and update session history.
  1259.  
  1260.     try {
  1261.       getWebNavigation().gotoIndex(index);
  1262.     }
  1263.     catch(ex) {
  1264.       return false;
  1265.     }
  1266.     return true;
  1267.   }
  1268.   else {
  1269.     // Modified click.  Go there in a new tab/window.
  1270.     // This code doesn't copy history or work well with framed pages.
  1271.  
  1272.     var sessionHistory = getWebNavigation().sessionHistory;
  1273.     var entry = sessionHistory.getEntryAtIndex(index, false);
  1274.     var url = entry.URI.spec;
  1275.     openUILinkIn(url, where, false);
  1276.     return true;
  1277.   }
  1278. }
  1279.  
  1280. function BrowserForward(aEvent, aIgnoreAlt)
  1281. {
  1282.   var where = whereToOpenLink(aEvent, false, aIgnoreAlt);
  1283.  
  1284.   if (where == "current") {
  1285.     try {
  1286.       getWebNavigation().goForward();
  1287.     }
  1288.     catch(ex) {
  1289.     }
  1290.   }
  1291.   else {
  1292.     var sessionHistory = getWebNavigation().sessionHistory;
  1293.     var currentIndex = sessionHistory.index;
  1294.     var entry = sessionHistory.getEntryAtIndex(currentIndex + 1, false);
  1295.     var url = entry.URI.spec;
  1296.     openUILinkIn(url, where);
  1297.   }
  1298. }
  1299.  
  1300. function BrowserBack(aEvent, aIgnoreAlt)
  1301. {
  1302.   var where = whereToOpenLink(aEvent, false, aIgnoreAlt);
  1303.  
  1304.   if (where == "current") {
  1305.     try {
  1306.       getWebNavigation().goBack();
  1307.     }
  1308.     catch(ex) {
  1309.     }
  1310.   }
  1311.   else {
  1312.     var sessionHistory = getWebNavigation().sessionHistory;
  1313.     var currentIndex = sessionHistory.index;
  1314.     var entry = sessionHistory.getEntryAtIndex(currentIndex - 1, false);
  1315.     var url = entry.URI.spec;
  1316.     openUILinkIn(url, where);
  1317.   }
  1318. }
  1319.  
  1320. function BrowserHandleBackspace()
  1321. {
  1322.   switch (gPrefService.getIntPref("browser.backspace_action")) {
  1323.   case 0:
  1324.     BrowserBack();
  1325.     break;
  1326.   case 1:
  1327.     goDoCommand("cmd_scrollPageUp");
  1328.     break;
  1329.   }
  1330. }
  1331.  
  1332. function BrowserHandleShiftBackspace()
  1333. {
  1334.   switch (gPrefService.getIntPref("browser.backspace_action")) {
  1335.   case 0:
  1336.     BrowserForward();
  1337.     break;
  1338.   case 1:
  1339.     goDoCommand("cmd_scrollPageDown");
  1340.     break;
  1341.   }
  1342. }
  1343.  
  1344. function BrowserBackMenu(event)
  1345. {
  1346.   return FillHistoryMenu(event.target, "back");
  1347. }
  1348.  
  1349. function BrowserForwardMenu(event)
  1350. {
  1351.   return FillHistoryMenu(event.target, "forward");
  1352. }
  1353.  
  1354. function BrowserStop()
  1355. {
  1356.   try {
  1357.     const stopFlags = nsIWebNavigation.STOP_ALL;
  1358.     getWebNavigation().stop(stopFlags);
  1359.   }
  1360.   catch(ex) {
  1361.   }
  1362. }
  1363.  
  1364. function BrowserReload()
  1365. {
  1366.   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_NONE;
  1367.   return BrowserReloadWithFlags(reloadFlags);
  1368. }
  1369.  
  1370. function BrowserReloadSkipCache()
  1371. {
  1372.   // Bypass proxy and cache.
  1373.   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
  1374.   return BrowserReloadWithFlags(reloadFlags);
  1375. }
  1376.  
  1377. function BrowserHome()
  1378. {
  1379.   var homePage = gHomeButton.getHomePage();
  1380.   FlockHomePageMetrics(homePage);
  1381.   loadOneOrMoreURIs(homePage);
  1382. }
  1383.  
  1384. function BrowserHomeClick(aEvent)
  1385. {
  1386.   if (aEvent.button == 2) // right-click: do nothing
  1387.     return;
  1388.  
  1389.   var homePage = gHomeButton.getHomePage();
  1390.   FlockHomePageMetrics(homePage);
  1391.   var where = whereToOpenLink(aEvent);
  1392.   var urls;
  1393.  
  1394.   // openUILinkIn in utilityOverlay.js doesn't handle loading multiple pages
  1395.   switch (where) {
  1396.   case "save":
  1397.     urls = homePage.split("|");
  1398.     saveURL(urls[0], null, null, true);  // only save the first page
  1399.     break;
  1400.   case "current":
  1401.     loadOneOrMoreURIs(homePage);
  1402.     break;
  1403.   case "tabshifted":
  1404.   case "tab":
  1405.     urls = homePage.split("|");
  1406.     var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground", false);
  1407.     gBrowser.loadTabs(urls, loadInBackground);
  1408.     break;
  1409.   case "window":
  1410.     OpenBrowserWindow();
  1411.     break;
  1412.   }
  1413. }
  1414.  
  1415. function FlockHomePageMetrics(aHomePage)
  1416. {
  1417.   var metrics = Components.classes["@flock.com/metrics-service;1"]
  1418.                           .getService(Components.interfaces.flockIMetricsService);
  1419.   metrics.reportCount("home page load");
  1420.   var urls = aHomePage.split("|");
  1421.   for (var i = 0; i < urls.length; i++) {
  1422.     if (urls[i] == "about:myworld") {
  1423.       metrics.reportCount("myworld from home page load");
  1424.       return;
  1425.     }
  1426.   }
  1427. }
  1428.  
  1429. function loadOneOrMoreURIs(aURIString)
  1430. {
  1431. //@line 1673 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1432.   // This function throws for certain malformed URIs, so use exception handling
  1433.   // so that we don't disrupt startup
  1434.   try {
  1435.     gBrowser.loadTabs(aURIString.split("|"), false, true);
  1436.   } 
  1437.   catch (e) {
  1438.   }
  1439. }
  1440.  
  1441. //@line 1683 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1442. function constructGoMenuItem(goMenu, beforeItem, url, title)
  1443. {
  1444.   var menuitem = document.createElementNS(kXULNS, "menuitem");
  1445.   menuitem.setAttribute("statustext", url);
  1446.   menuitem.setAttribute("label", title);
  1447.   goMenu.insertBefore(menuitem, beforeItem);
  1448.   return menuitem;
  1449. }
  1450.  
  1451. function onGoMenuHidden(aEvent)
  1452. {
  1453.   if (aEvent.target == aEvent.currentTarget)
  1454.     setTimeout(destroyGoMenuItems, 0, document.getElementById('goPopup'));
  1455. }
  1456.  
  1457. function destroyGoMenuItems(goMenu) {
  1458.   var startSeparator = document.getElementById("startHistorySeparator");
  1459.   var endSeparator = document.getElementById("endHistorySeparator");
  1460.   endSeparator.hidden = true;
  1461.  
  1462.   // Destroy the items.
  1463.   var destroy = false;
  1464.   for (var i = 0; i < goMenu.childNodes.length; i++) {
  1465.     var item = goMenu.childNodes[i];
  1466.     if (item == endSeparator)
  1467.       break;
  1468.  
  1469.     if (destroy) {
  1470.       i--;
  1471.       goMenu.removeChild(item);
  1472.     }
  1473.  
  1474.     if (item == startSeparator)
  1475.       destroy = true;
  1476.   }
  1477. }
  1478.  
  1479. function updateGoMenu(aEvent, goMenu)
  1480. {
  1481.   if (aEvent.target != aEvent.currentTarget)
  1482.     return;
  1483.  
  1484.   // In case the timer didn't fire.
  1485.   destroyGoMenuItems(goMenu);
  1486.  
  1487.   // enable/disable RCT sub menu
  1488.   // do this here, before the early return
  1489.   HistoryMenu.toggleRecentlyClosedTabs();
  1490.  
  1491.   var history = document.getElementById("hiddenHistoryTree");
  1492.  
  1493.   if (history.hidden) {
  1494.     history.hidden = false;
  1495.     var globalHistory = Components.classes["@mozilla.org/browser/global-history;2"]
  1496.                                   .getService(Components.interfaces.nsIRDFDataSource);
  1497.     history.database.AddDataSource(globalHistory);
  1498.   }
  1499.  
  1500.   if (!history.ref)
  1501.     history.ref = "NC:HistoryRoot";
  1502.  
  1503.   var count = history.view.rowCount;
  1504.   if (count > 10)
  1505.     count = 10;
  1506.  
  1507.   if (count == 0)
  1508.     return;
  1509.  
  1510.   const NC_NS     = "http://home.netscape.com/NC-rdf#";
  1511.  
  1512.   if (!gRDF)
  1513.      gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
  1514.                       .getService(Components.interfaces.nsIRDFService);
  1515.  
  1516.   var builder = history.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
  1517.  
  1518.   var beforeItem = document.getElementById("endHistorySeparator");
  1519.  
  1520.   var nameResource = gRDF.GetResource(NC_NS + "Name");
  1521.  
  1522.   var endSep = beforeItem;
  1523.   var showSep = false;
  1524.  
  1525.   for (var i = count-1; i >= 0; i--) {
  1526.     var res = builder.getResourceAtIndex(i);
  1527.     var url = res.Value;
  1528.     var titleRes = history.database.GetTarget(res, nameResource, true);
  1529.     if (!titleRes)
  1530.       continue;
  1531.  
  1532.     showSep = true;
  1533.     var titleLiteral = titleRes.QueryInterface(Components.interfaces.nsIRDFLiteral);
  1534.     beforeItem = constructGoMenuItem(goMenu, beforeItem, url, titleLiteral.Value);
  1535.   }
  1536.  
  1537.   if (showSep)
  1538.     endSep.hidden = false;
  1539. }
  1540.  
  1541. function addBookmarkAs(aBrowser, aBookmarkAllTabs, aIsWebPanel)
  1542. {
  1543.   const browsers = aBrowser.browsers;
  1544.  
  1545.   // we only disable the menu item on onpopupshowing; if we get
  1546.   // here via keyboard shortcut, we need to pretend like
  1547.   // nothing happened if we have no tabs
  1548.   if ((!browsers || browsers.length == 1) && aBookmarkAllTabs)
  1549.     return;
  1550.  
  1551.   if (browsers && browsers.length > 1)
  1552.     addBookmarkForTabBrowser(aBrowser, aBookmarkAllTabs);
  1553.   else
  1554.     addBookmarkForBrowser(aBrowser.webNavigation, aIsWebPanel);
  1555. }
  1556.  
  1557. function addBookmarkForTabBrowser(aTabBrowser, aBookmarkAllTabs, aSelect, aIsWebPanel)
  1558. {
  1559.  /* var tabsInfo = [];
  1560.   var currentTabInfo = { name: "", url: "", charset: null };
  1561.  
  1562.   const activeBrowser = aTabBrowser.selectedBrowser;
  1563.   const browsers = aTabBrowser.browsers;
  1564.   for (var i = 0; i < browsers.length; ++i) {
  1565.     var webNav = browsers[i].webNavigation;
  1566.     var url = webNav.currentURI.spec;
  1567.     var name = "";
  1568.     var charSet, description;
  1569.     try {
  1570.       var doc = webNav.document;
  1571.       name = doc.title || url;
  1572.       charSet = doc.characterSet;
  1573.       description = BookmarksUtils.getDescriptionFromDocument(doc);
  1574.     } catch (e) {
  1575.       name = url;
  1576.     }
  1577.     tabsInfo[i] = { name: name, url: url, charset: charSet, description: description };
  1578.     if (browsers[i] == activeBrowser)
  1579.       currentTabInfo = tabsInfo[i];
  1580.   }
  1581.   var dialogArgs = currentTabInfo;
  1582.   if (aBookmarkAllTabs) {
  1583.     dialogArgs = { name: gNavigatorBundle.getString("bookmarkAllTabsDefault") };
  1584.     dialogArgs.bBookmarkAllTabs = true;
  1585.   }
  1586.  
  1587.   dialogArgs.objGroup = tabsInfo;
  1588.   */
  1589.   if (aBookmarkAllTabs) {
  1590.     BookmarksUtils.addBookmarkForAllTabs(aTabBrowser);
  1591.   }
  1592.   else
  1593.     addBookmarkForBrowser(aTabBrowser.webNavigation, aIsWebPanel);
  1594. }
  1595.  
  1596. function addBookmarkForBrowser(aDocShell, aIsWebPanel)
  1597. {
  1598.   // Bug 52536: We obtain the URL and title from the nsIWebNavigation
  1599.   // associated with a <browser/> rather than from a DOMWindow.
  1600.   // This is because when a full page plugin is loaded, there is
  1601.   // no DOMWindow (?) but information about the loaded document
  1602.   // may still be obtained from the webNavigation.
  1603.   var url = aDocShell.currentURI.spec;
  1604.   var title, charSet = null;
  1605.   var description;
  1606.   try {
  1607.     title = aDocShell.document.title || url;
  1608.     charSet = aDocShell.document.characterSet;
  1609.     description = BookmarksUtils.getDescriptionFromDocument(aDocShell.document);
  1610.   }
  1611.   catch (e) {
  1612.     title = url;
  1613.   }
  1614.   BookmarksUtils.addBookmark(url, title, charSet, aIsWebPanel, description);
  1615. }
  1616. //@line 1858 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1617.  
  1618. function openLocation()
  1619. {
  1620.   if (gURLBar) {
  1621.     var style = document.defaultView.getComputedStyle(gURLBarContainer, null);
  1622.     if (style.visibility == "visible" && style.display != "none") {
  1623.       gURLBar.focus();
  1624.       gURLBar.select();
  1625.       return;
  1626.     }
  1627.   }
  1628. //@line 1886 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1629.   openDialog("chrome://browser/content/openLocation.xul", "_blank",
  1630.              "chrome,modal,titlebar", window);
  1631. }
  1632.  
  1633. function openLocationCallback()
  1634. {
  1635.   // make sure the DOM is ready
  1636.   setTimeout(function() { this.openLocation(); }, 0);
  1637. }
  1638.  
  1639. function BrowserOpenTab()
  1640. {
  1641.   gBrowser.loadOneTab("about:blank", null, null, null, false, false);
  1642.   if (gURLBar)
  1643.     setTimeout(function() { gURLBar.focus(); }, 0);
  1644. }
  1645.  
  1646. /* Called from the openLocation dialog. This allows that dialog to instruct
  1647.    its opener to open a new window and then step completely out of the way.
  1648.    Anything less byzantine is causing horrible crashes, rather believably,
  1649.    though oddly only on Linux. */
  1650. function delayedOpenWindow(chrome, flags, href, postData)
  1651. {
  1652.   // The other way to use setTimeout,
  1653.   // setTimeout(openDialog, 10, chrome, "_blank", flags, url),
  1654.   // doesn't work here.  The extra "magic" extra argument setTimeout adds to
  1655.   // the callback function would confuse prepareForStartup() by making
  1656.   // window.arguments[1] be an integer instead of null.
  1657.   setTimeout(function() { openDialog(chrome, "_blank", flags, href, null, null, postData); }, 10);
  1658. }
  1659.  
  1660. /* Required because the tab needs time to set up its content viewers and get the load of
  1661.    the URI kicked off before becoming the active content area. */
  1662. function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup)
  1663. {
  1664.   gBrowser.loadOneTab(aUrl, aReferrer, aCharset, aPostData, false, aAllowThirdPartyFixup);
  1665. }
  1666.  
  1667. function BrowserOpenFileWindow()
  1668. {
  1669.   // Get filepicker component.
  1670.   try {
  1671.     const nsIFilePicker = Components.interfaces.nsIFilePicker;
  1672.     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  1673.     fp.init(window, gNavigatorBundle.getString("openFile"), nsIFilePicker.modeOpen);
  1674.     fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText | nsIFilePicker.filterImages |
  1675.                      nsIFilePicker.filterXML | nsIFilePicker.filterHTML);
  1676.  
  1677.     if (fp.show() == nsIFilePicker.returnOK)
  1678.       openTopWin(fp.fileURL.spec);
  1679.   } catch (ex) {
  1680.   }
  1681. }
  1682.  
  1683. function BrowserCloseTabOrWindow()
  1684. {
  1685. //@line 1949 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1686.  
  1687.   if (gBrowser.localName == "tabbrowser" && (gBrowser.tabContainer.childNodes.length > 1 ||
  1688.       !gPrefService.getBoolPref("browser.tabs.autoHide") && window.toolbar.visible)) {
  1689.     // Just close up a tab (and focus the address bar if it was the last one).
  1690.     if (gBrowser.tabContainer.childNodes.length == 1 && gURLBar)
  1691.       setTimeout(function() { gURLBar.focus(); }, 0);
  1692.     gBrowser.removeCurrentTab();
  1693.     return;
  1694.   }
  1695.  
  1696.   BrowserCloseWindow();
  1697. }
  1698.  
  1699. function BrowserTryToCloseWindow()
  1700. {
  1701.   //give tryToClose a chance to veto if it is defined
  1702.   if (typeof(window.tryToClose) != "function" || window.tryToClose())
  1703.     BrowserCloseWindow();
  1704. }
  1705.  
  1706. function BrowserCloseWindow()
  1707. {
  1708.   // This code replicates stuff in BrowserShutdown().  It is here because
  1709.   // window.screenX and window.screenY have real values.  We need
  1710.   // to fix this eventually but by replicating the code here, we
  1711.   // provide a means of saving position (it just requires that the
  1712.   // user close the window via File->Close (vs. close box).
  1713.  
  1714.   // Get the current window position/size.
  1715.   var x = window.screenX;
  1716.   var y = window.screenY;
  1717.   var h = window.outerHeight;
  1718.   var w = window.outerWidth;
  1719.  
  1720.   // Store these into the window attributes (for persistence).
  1721.   var win = document.getElementById( "main-window" );
  1722.   win.setAttribute( "x", x );
  1723.   win.setAttribute( "y", y );
  1724.   win.setAttribute( "height", h );
  1725.   win.setAttribute( "width", w );
  1726.  
  1727.   closeWindow(true);
  1728. }
  1729.  
  1730. function loadURI(uri, referrer, postData, allowThirdPartyFixup)
  1731. {
  1732.   try {
  1733.     if (postData === undefined)
  1734.       postData = null;
  1735.     var flags = nsIWebNavigation.LOAD_FLAGS_NONE;
  1736.     if (allowThirdPartyFixup) {
  1737.       flags = nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
  1738.     }
  1739.     getWebNavigation().loadURI(uri, flags, referrer, postData, null);
  1740.   } catch (e) {
  1741.   }
  1742. }
  1743.  
  1744. function BrowserLoadURL(aTriggeringEvent, aPostData) {
  1745.   var url = gURLBar.value;
  1746.  
  1747.   if (aTriggeringEvent instanceof MouseEvent) {
  1748.     if (aTriggeringEvent.button == 2)
  1749.       return; // Do nothing for right clicks
  1750.  
  1751.     // We have a mouse event (from the go button), so use the standard
  1752.     // UI link behaviors
  1753.     openUILink(url, aTriggeringEvent, false, false,
  1754.                true /* allow third party fixup */, aPostData);
  1755.     return;
  1756.   }
  1757.  
  1758.   if (aTriggeringEvent && aTriggeringEvent.altKey) {
  1759.     handleURLBarRevert();
  1760.     content.focus();
  1761.     gBrowser.loadOneTab(url, null, null, aPostData, false,
  1762.                         true /* allow third party fixup */);
  1763.     aTriggeringEvent.preventDefault();
  1764.     aTriggeringEvent.stopPropagation();
  1765.   }
  1766.   else
  1767.     loadURI(url, null, aPostData, true /* allow third party fixup */);
  1768.  
  1769.   content.focus();
  1770. }
  1771.  
  1772. function getShortcutOrURI(aURL, aPostDataRef)
  1773. {
  1774.   // rjc: added support for URL shortcuts (3/30/1999)
  1775.   try {
  1776.     var shortcutURL = null;
  1777. //@line 2047 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1778.     shortcutURL = BMSVC.resolveKeyword(aURL, aPostDataRef);
  1779. //@line 2049 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1780.     if (!shortcutURL) {
  1781.       // rjc: add support for string substitution with shortcuts (4/4/2000)
  1782.       //      (see bug # 29871 for details)
  1783.       var aOffset = aURL.indexOf(" ");
  1784.       if (aOffset > 0) {
  1785.         var cmd = aURL.substr(0, aOffset);
  1786.         var text = aURL.substr(aOffset+1);
  1787. //@line 2061 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1788.         shortcutURL = BMSVC.resolveKeyword(cmd, aPostDataRef);
  1789. //@line 2063 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1790.         if (shortcutURL && text) {
  1791.           var encodedText = null; 
  1792.           var charset = "";
  1793.           const re = /^(.*)\&mozcharset=([a-zA-Z][_\-a-zA-Z0-9]+)\s*$/; 
  1794.           var matches = shortcutURL.match(re);
  1795.           if (matches) {
  1796.              shortcutURL = matches[1];
  1797.              charset = matches[2];
  1798.           }
  1799. //@line 2073 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1800.           // FIXME: Bug 327328, we don't have last charset in places yet.
  1801.           else if (/%s/.test(shortcutURL) || 
  1802.                    (aPostDataRef && /%s/.test(aPostDataRef.value))) {
  1803.             try {
  1804.               charset = BMSVC.getLastCharset(shortcutURL);
  1805.             } catch (ex) {
  1806.             }
  1807.           }
  1808. //@line 2082 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1809.  
  1810.           if (charset)
  1811.             encodedText = escape(convertFromUnicode(charset, text)); 
  1812.           else  // default case: charset=UTF-8
  1813.             encodedText = encodeURIComponent(text);
  1814.  
  1815.           if (aPostDataRef && aPostDataRef.value) {
  1816.             // XXXben - currently we only support "application/x-www-form-urlencoded"
  1817.             //          enctypes.
  1818.             aPostDataRef.value = unescape(aPostDataRef.value);
  1819.             if (aPostDataRef.value.match(/%[sS]/)) {
  1820.               aPostDataRef.value = getPostDataStream(aPostDataRef.value,
  1821.                                                      text, encodedText,
  1822.                                                      "application/x-www-form-urlencoded");
  1823.             }
  1824.             else {
  1825.               shortcutURL = null;
  1826.               aPostDataRef.value = null;
  1827.             }
  1828.           }
  1829.           else {
  1830.             if (/%[sS]/.test(shortcutURL))
  1831.               shortcutURL = shortcutURL.replace(/%s/g, encodedText)
  1832.                                        .replace(/%S/g, text);
  1833.             else 
  1834.               shortcutURL = null;
  1835.           }
  1836.         }
  1837.       }
  1838.     }
  1839.  
  1840.     if (shortcutURL)
  1841.       aURL = shortcutURL;
  1842.  
  1843.   } catch (ex) {
  1844.   }
  1845.   return aURL;
  1846. }
  1847.  
  1848. //@line 2136 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1849. function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType)
  1850. {
  1851.   var dataStream = Components.classes["@mozilla.org/io/string-input-stream;1"]
  1852.                             .createInstance(Components.interfaces.nsIStringInputStream);
  1853.   aStringData = aStringData.replace(/%s/g, aEncKeyword).replace(/%S/g, aKeyword);
  1854. //@line 2143 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1855.   dataStream.setData(aStringData, aStringData.length);
  1856. //@line 2147 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1857.  
  1858.   var mimeStream = Components.classes["@mozilla.org/network/mime-input-stream;1"]
  1859.                               .createInstance(Components.interfaces.nsIMIMEInputStream);
  1860.   mimeStream.addHeader("Content-Type", aType);
  1861.   mimeStream.addContentLength = true;
  1862.   mimeStream.setData(dataStream);
  1863.   return mimeStream.QueryInterface(Components.interfaces.nsIInputStream);
  1864. }
  1865.  
  1866.  
  1867. function readFromClipboard()
  1868. {
  1869.   var url;
  1870.  
  1871.   try {
  1872.     // Get clipboard.
  1873.     var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
  1874.                               .getService(Components.interfaces.nsIClipboard);
  1875.  
  1876.     // Create tranferable that will transfer the text.
  1877.     var trans = Components.classes["@mozilla.org/widget/transferable;1"]
  1878.                           .createInstance(Components.interfaces.nsITransferable);
  1879.  
  1880.     trans.addDataFlavor("text/unicode");
  1881.  
  1882.     // If available, use selection clipboard, otherwise global one
  1883.     if (clipboard.supportsSelectionClipboard())
  1884.       clipboard.getData(trans, clipboard.kSelectionClipboard);
  1885.     else
  1886.       clipboard.getData(trans, clipboard.kGlobalClipboard);
  1887.  
  1888.     var data = {};
  1889.     var dataLen = {};
  1890.     trans.getTransferData("text/unicode", data, dataLen);
  1891.  
  1892.     if (data) {
  1893.       data = data.value.QueryInterface(Components.interfaces.nsISupportsString);
  1894.       url = data.data.substring(0, dataLen.value / 2);
  1895.     }
  1896.   } catch (ex) {
  1897.   }
  1898.  
  1899.   return url;
  1900. }
  1901.  
  1902. function BrowserViewSourceOfDocument(aDocument)
  1903. {
  1904.   var pageCookie;
  1905.   var webNav;
  1906.  
  1907.   // Get the document charset
  1908.   var docCharset = "charset=" + aDocument.characterSet;
  1909.  
  1910.   // Get the nsIWebNavigation associated with the document
  1911.   try {
  1912.       var win;
  1913.       var ifRequestor;
  1914.  
  1915.       // Get the DOMWindow for the requested document.  If the DOMWindow
  1916.       // cannot be found, then just use the content window...
  1917.       //
  1918.       // XXX:  This is a bit of a hack...
  1919.       win = aDocument.defaultView;
  1920.       if (win == window) {
  1921.         win = content;
  1922.       }
  1923.       ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  1924.  
  1925.       webNav = ifRequestor.getInterface(nsIWebNavigation);
  1926.   } catch(err) {
  1927.       // If nsIWebNavigation cannot be found, just get the one for the whole
  1928.       // window...
  1929.       webNav = getWebNavigation();
  1930.   }
  1931.   //
  1932.   // Get the 'PageDescriptor' for the current document. This allows the
  1933.   // view-source to access the cached copy of the content rather than
  1934.   // refetching it from the network...
  1935.   //
  1936.   try{
  1937.     var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor);
  1938.  
  1939.     pageCookie = PageLoader.currentDescriptor;
  1940.   } catch(err) {
  1941.     // If no page descriptor is available, just use the view-source URL...
  1942.   }
  1943.  
  1944.   ViewSourceOfURL(webNav.currentURI.spec, pageCookie, aDocument);
  1945. }
  1946.  
  1947. function ViewSourceOfURL(aURL, aPageDescriptor, aDocument)
  1948. {
  1949.   if (getBoolPref("view_source.editor.external", false)) {
  1950.     gViewSourceUtils.openInExternalEditor(aURL, aPageDescriptor, aDocument);
  1951.   }
  1952.   else {
  1953.     gViewSourceUtils.openInInternalViewer(aURL, aPageDescriptor, aDocument);
  1954.   }
  1955. }
  1956.  
  1957. // doc - document to use for source, or null for this window's document
  1958. // initialTab - name of the initial tab to display, or null for the first tab
  1959. function BrowserPageInfo(doc, initialTab)
  1960. {
  1961.   var args = {doc: doc, initialTab: initialTab};
  1962.   toOpenDialogByTypeAndUrl("Browser:page-info",
  1963.                            doc ? doc.location : window.content.document.location,
  1964.                            "chrome://browser/content/pageInfo.xul",
  1965.                            "chrome,dialog=no",
  1966.                            args);
  1967. }
  1968.  
  1969. //@line 2308 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  1970.  
  1971. function checkForDirectoryListing()
  1972. {
  1973.   if ( "HTTPIndex" in content &&
  1974.        content.HTTPIndex instanceof Components.interfaces.nsIHTTPIndex ) {
  1975.     content.wrappedJSObject.defaultCharacterset =
  1976.       getMarkupDocumentViewer().defaultCharacterSet;
  1977.   }
  1978. }
  1979.  
  1980. // If "ESC" is pressed in the url bar, we replace the urlbar's value with the url of the page
  1981. // and highlight it, unless it is about:blank, where we reset it to "".
  1982. function handleURLBarRevert()
  1983. {
  1984.   var url = getWebNavigation().currentURI.spec;
  1985.   var throbberElement = document.getElementById("navigator-throbber");
  1986.  
  1987.   var isScrolling = gURLBar.popupOpen;
  1988.  
  1989.   // don't revert to last valid url unless page is NOT loading
  1990.   // and user is NOT key-scrolling through autocomplete list
  1991.   if ((!throbberElement || !throbberElement.hasAttribute("busy")) && !isScrolling) {
  1992.     if (url != "about:blank" || content.opener) {
  1993.       gURLBar.value = url;
  1994.       gURLBar.select();
  1995.       SetPageProxyState("valid");
  1996.     } else { //if about:blank, urlbar becomes ""
  1997.       gURLBar.value = "";
  1998.     }
  1999.   }
  2000.  
  2001.   gBrowser.userTypedValue = null;
  2002.  
  2003.   // tell widget to revert to last typed text only if the user
  2004.   // was scrolling when they hit escape
  2005.   return !isScrolling;
  2006. }
  2007.  
  2008. function handleURLBarCommand(aTriggeringEvent) {
  2009.   var postData = { };
  2010.   canonizeUrl(aTriggeringEvent, postData);
  2011.  
  2012.   try {
  2013.     addToUrlbarHistory(gURLBar.value);
  2014.   } catch (ex) {
  2015.     // Things may go wrong when adding url to session history,
  2016.     // but don't let that interfere with the loading of the url.
  2017.   }
  2018.  
  2019.   BrowserLoadURL(aTriggeringEvent, postData.value);
  2020. }
  2021.  
  2022. function canonizeUrl(aTriggeringEvent, aPostDataRef) {
  2023.   if (!gURLBar || !gURLBar.value)
  2024.     return;
  2025.  
  2026.   var url = gURLBar.value;
  2027.  
  2028.   // Only add the suffix when the URL bar value isn't already "URL-like".
  2029.   // Since this function is called from handleURLBarCommand, which receives
  2030.   // both mouse (from the go button) and keyboard events, we also make sure not
  2031.   // to do the fixup unless we get a keyboard event, to match user expectations.
  2032.   if (!/^(www|http)|\/\s*$/i.test(url) &&
  2033.       (aTriggeringEvent instanceof KeyEvent)) {
  2034. //@line 2375 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2035.     var accel = aTriggeringEvent.ctrlKey;
  2036. //@line 2377 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2037.     var shift = aTriggeringEvent.shiftKey;
  2038.  
  2039.     var suffix = "";
  2040.  
  2041.     switch (true) {
  2042.       case (accel && shift):
  2043.         suffix = ".org/";
  2044.         break;
  2045.       case (shift):
  2046.         suffix = ".net/";
  2047.         break;
  2048.       case (accel):
  2049.         try {
  2050.           suffix = gPrefService.getCharPref("browser.fixup.alternate.suffix");
  2051.           if (suffix.charAt(suffix.length - 1) != "/")
  2052.             suffix += "/";
  2053.         } catch(e) {
  2054.           suffix = ".com/";
  2055.         }
  2056.         break;
  2057.     }
  2058.  
  2059.     if (suffix) {
  2060.       // trim leading/trailing spaces (bug 233205)
  2061.       url = url.replace(/^\s+/, "").replace(/\s+$/, "");
  2062.  
  2063.       // Tack www. and suffix on.  If user has appended directories, insert
  2064.       // suffix before them (bug 279035).  Be careful not to get two slashes.
  2065.       var firstSlash = url.indexOf("/");
  2066.       if (firstSlash >= 0)
  2067.         url = "http://www." + url.substring(0, firstSlash) + suffix +
  2068.               url.substring(firstSlash + 1, url.length);
  2069.       else
  2070.         url = "http://www." + url + suffix;
  2071.     }
  2072.   }
  2073.  
  2074.   gURLBar.value = getShortcutOrURI(url, aPostDataRef);
  2075. }
  2076.  
  2077. function UpdatePageProxyState()
  2078. {
  2079.   if (gURLBar && gURLBar.value != gLastValidURLStr)
  2080.     SetPageProxyState("invalid");
  2081. }
  2082.  
  2083. function SetPageProxyState(aState)
  2084. {
  2085.   if (!gURLBar)
  2086.     return;
  2087.  
  2088.   if (!gProxyButton)
  2089.     gProxyButton = document.getElementById("page-proxy-button");
  2090.   if (!gProxyFavIcon)
  2091.     gProxyFavIcon = document.getElementById("page-proxy-favicon");
  2092.   if (!gProxyDeck)
  2093.     gProxyDeck = document.getElementById("page-proxy-deck");
  2094.  
  2095.   gProxyButton.setAttribute("pageproxystate", aState);
  2096.  
  2097.   // the page proxy state is set to valid via OnLocationChange, which
  2098.   // gets called when we switch tabs.
  2099.   if (aState == "valid") {
  2100.     gLastValidURLStr = gURLBar.value;
  2101.     gURLBar.addEventListener("input", UpdatePageProxyState, false);
  2102.  
  2103.     PageProxySetIcon(gBrowser.mCurrentBrowser.mIconURL);
  2104.   } else if (aState == "invalid") {
  2105.     gURLBar.removeEventListener("input", UpdatePageProxyState, false);
  2106.     PageProxyClearIcon();
  2107.   }
  2108. }
  2109.  
  2110. function PageProxySetIcon (aURL)
  2111. {
  2112.   if (!gProxyFavIcon)
  2113.     return;
  2114.  
  2115.   if (!aURL)
  2116.     PageProxyClearIcon();
  2117.   else if (gProxyFavIcon.getAttribute("src") != aURL)
  2118.     gProxyFavIcon.setAttribute("src", aURL);
  2119.   else if (gProxyDeck.selectedIndex != 1)
  2120.     gProxyDeck.selectedIndex = 1;
  2121. }
  2122.  
  2123. function PageProxyClearIcon ()
  2124. {
  2125.   if (gProxyDeck.selectedIndex != 0)
  2126.     gProxyDeck.selectedIndex = 0;
  2127.   if (gProxyFavIcon.hasAttribute("src"))
  2128.     gProxyFavIcon.removeAttribute("src");
  2129. }
  2130.  
  2131. function PageProxyDragGesture(aEvent)
  2132. {
  2133.   if (gProxyButton.getAttribute("pageproxystate") == "valid") {
  2134.     nsDragAndDrop.startDrag(aEvent, proxyIconDNDObserver);
  2135.     return true;
  2136.   }
  2137.   return false;
  2138. }
  2139.  
  2140. function PageProxyClickHandler(aEvent)
  2141. {
  2142.   switch (aEvent.button) {
  2143.     case 0:
  2144.       gURLBar.select();
  2145.       break;
  2146.     case 1:
  2147.       if (gPrefService.getBoolPref("middlemouse.paste"))
  2148.         middleMousePaste(aEvent);
  2149.       break;
  2150.   }
  2151.   return true;
  2152. }
  2153.  
  2154. function URLBarOnDrop(evt)
  2155. {
  2156.   nsDragAndDrop.drop(evt, urlbarObserver);
  2157. }
  2158.  
  2159. var urlbarObserver = {
  2160.   onDrop: function (aEvent, aXferData, aDragSession)
  2161.     {
  2162.       var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
  2163.  
  2164.       // The URL bar automatically handles inputs with newline characters,
  2165.       // so we can get away with treating text/x-moz-url flavours as text/unicode.
  2166.       if (url) {
  2167.         getBrowser().dragDropSecurityCheck(aEvent, aDragSession, url);
  2168.  
  2169.         try {
  2170.           gURLBar.value = url;
  2171.           const nsIScriptSecMan = Components.interfaces.nsIScriptSecurityManager;
  2172.           urlSecurityCheck(gURLBar.value, gBrowser.currentURI.spec,
  2173.                            nsIScriptSecMan.DISALLOW_SCRIPT_OR_DATA);
  2174.           handleURLBarCommand();
  2175.         } catch (ex) {}
  2176.       }
  2177.     },
  2178.   getSupportedFlavours: function ()
  2179.     {
  2180.       var flavourSet = new FlavourSet();
  2181.  
  2182.       // Plain text drops are often misidentified as "text/x-moz-url", so favor plain text.
  2183.       flavourSet.appendFlavour("text/unicode");
  2184.       flavourSet.appendFlavour("text/x-moz-url");
  2185.       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2186.       return flavourSet;
  2187.     }
  2188. }
  2189.  
  2190. function updateToolbarStates(toolbarMenuElt)
  2191. {
  2192.   if (!gHaveUpdatedToolbarState) {
  2193.     var mainWindow = document.getElementById("main-window");
  2194.     if (mainWindow.hasAttribute("chromehidden")) {
  2195.       gHaveUpdatedToolbarState = true;
  2196.       var i;
  2197.       for (i = 0; i < toolbarMenuElt.childNodes.length; ++i)
  2198.         document.getElementById(toolbarMenuElt.childNodes[i].getAttribute("observes")).removeAttribute("checked");
  2199.       var toolbars = document.getElementsByTagName("toolbar");
  2200.  
  2201.       // Start i at 1, since we skip the menubar.
  2202.       for (i = 1; i < toolbars.length; ++i) {
  2203.         if (toolbars[i].getAttribute("class").indexOf("chromeclass") != -1)
  2204.           toolbars[i].setAttribute("collapsed", "true");
  2205.       }
  2206.       var statusbars = document.getElementsByTagName("statusbar");
  2207.       for (i = 1; i < statusbars.length; ++i) {
  2208.         if (statusbars[i].getAttribute("class").indexOf("chromeclass") != -1)
  2209.           statusbars[i].setAttribute("collapsed", "true");
  2210.       }
  2211.       mainWindow.removeAttribute("chromehidden");
  2212.     }
  2213.   }
  2214. }
  2215.  
  2216. function BrowserImport()
  2217. {
  2218. //@line 2569 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2219.   window.openDialog("chrome://browser/content/migration/migration.xul",
  2220.                     "migration", "modal,centerscreen,chrome,resizable=no");
  2221. //@line 2572 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2222. }
  2223.  
  2224. function BrowserFullScreen()
  2225. {
  2226.   window.fullScreen = !window.fullScreen;
  2227. }
  2228.  
  2229. function onFullScreen()
  2230. {
  2231.   FullScreen.toggle();
  2232. }
  2233.  
  2234. function getWebNavigation()
  2235. {
  2236.   try {
  2237.     return gBrowser.webNavigation;
  2238.   } catch (e) {
  2239.     return null;
  2240.   }
  2241. }
  2242.  
  2243. function BrowserReloadWithFlags(reloadFlags)
  2244. {
  2245.   /* First, we'll try to use the session history object to reload so
  2246.    * that framesets are handled properly. If we're in a special
  2247.    * window (such as view-source) that has no session history, fall
  2248.    * back on using the web navigation's reload method.
  2249.    */
  2250.  
  2251.   var webNav = getWebNavigation();
  2252.   try {
  2253.     var sh = webNav.sessionHistory;
  2254.     if (sh)
  2255.       webNav = sh.QueryInterface(nsIWebNavigation);
  2256.   } catch (e) {
  2257.   }
  2258.  
  2259.   try {
  2260.     webNav.reload(reloadFlags);
  2261.   } catch (e) {
  2262.   }
  2263. }
  2264.  
  2265. function toggleAffectedChrome(aHide)
  2266. {
  2267.   // chrome to toggle includes:
  2268.   //   (*) menubar
  2269.   //   (*) navigation bar
  2270.   //   (*) bookmarks toolbar
  2271.   //   (*) browser messages
  2272.   //   (*) sidebar
  2273.   //   (*) find bar
  2274.   //   (*) statusbar
  2275.  
  2276.   var navToolbox = document.getElementById("navigator-toolbox");
  2277.   navToolbox.hidden = aHide;
  2278.   if (aHide)
  2279.   {
  2280.     gChromeState = {};
  2281.     var sidebar = document.getElementById("sidebar-box");
  2282.     gChromeState.sidebarOpen = !sidebar.hidden;
  2283.     gSidebarCommand = sidebar.getAttribute("sidebarcommand");
  2284.  
  2285.     var notificationBox = gBrowser.getNotificationBox();
  2286.     gChromeState.notificationsOpen = !notificationBox.notificationsHidden;
  2287.     notificationBox.notificationsHidden = aHide;
  2288.  
  2289.     var statusbar = document.getElementById("status-bar");
  2290.     gChromeState.statusbarOpen = !statusbar.hidden;
  2291.     statusbar.hidden = aHide;
  2292.  
  2293.     var findBar = document.getElementById("FindToolbar");
  2294.     gChromeState.findOpen = !findBar.hidden;
  2295.     gFindBar.closeFindBar();
  2296.   }
  2297.   else {
  2298.     if (gChromeState.notificationsOpen) {
  2299.       gBrowser.getNotificationBox().notificationsHidden = aHide;
  2300.     }
  2301.  
  2302.     if (gChromeState.statusbarOpen) {
  2303.       var statusbar = document.getElementById("status-bar");
  2304.       statusbar.hidden = aHide;
  2305.     }
  2306.  
  2307.     if (gChromeState.findOpen)
  2308.       gFindBar.openFindBar();
  2309.   }
  2310.  
  2311.   if (gChromeState.sidebarOpen)
  2312.     toggleSidebar(gSidebarCommand);
  2313. }
  2314.  
  2315. function onEnterPrintPreview()
  2316. {
  2317.   toggleAffectedChrome(true);
  2318. }
  2319.  
  2320. function onExitPrintPreview()
  2321. {
  2322.   // restore chrome to original state
  2323.   toggleAffectedChrome(false);
  2324. }
  2325.  
  2326. function getMarkupDocumentViewer()
  2327. {
  2328.   return gBrowser.markupDocumentViewer;
  2329. }
  2330.  
  2331. /**
  2332.  * Content area tooltip.
  2333.  * XXX - this must move into XBL binding/equiv! Do not want to pollute
  2334.  *       browser.js with functionality that can be encapsulated into
  2335.  *       browser widget. TEMPORARY!
  2336.  *
  2337.  * NOTE: Any changes to this routine need to be mirrored in ChromeListener::FindTitleText()
  2338.  *       (located in mozilla/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp)
  2339.  *       which performs the same function, but for embedded clients that
  2340.  *       don't use a XUL/JS layer. It is important that the logic of
  2341.  *       these two routines be kept more or less in sync.
  2342.  *       (pinkerton)
  2343.  **/
  2344. function FillInHTMLTooltip(tipElement)
  2345. {
  2346.   var retVal = false;
  2347.   if (tipElement.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
  2348.     return retVal;
  2349.  
  2350.   const XLinkNS = "http://www.w3.org/1999/xlink";
  2351.  
  2352.  
  2353.   var titleText = null;
  2354.   var XLinkTitleText = null;
  2355.  
  2356.   while (!titleText && !XLinkTitleText && tipElement) {
  2357.     if (tipElement.nodeType == Node.ELEMENT_NODE) {
  2358.       titleText = tipElement.getAttribute("title");
  2359.       XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
  2360.     }
  2361.     tipElement = tipElement.parentNode;
  2362.   }
  2363.  
  2364.   var texts = [titleText, XLinkTitleText];
  2365.   var tipNode = document.getElementById("aHTMLTooltip");
  2366.  
  2367.   for (var i = 0; i < texts.length; ++i) {
  2368.     var t = texts[i];
  2369.     if (t && t.search(/\S/) >= 0) {
  2370.       // XXX - Short-term fix to bug 67127: collapse whitespace here
  2371.       tipNode.setAttribute("label", t.replace(/\s+/g, " ") );
  2372.       retVal = true;
  2373.     }
  2374.   }
  2375.  
  2376.   return retVal;
  2377. }
  2378.  
  2379. var proxyIconDNDObserver = {
  2380.   onDragStart: function (aEvent, aXferData, aDragAction)
  2381.     {
  2382.       var value = gURLBar.value;
  2383.       // XXX - do we want to allow the user to set a blank page to their homepage?
  2384.       //       if so then we want to modify this a little to set about:blank as
  2385.       //       the homepage in the event of an empty urlbar.
  2386.       if (!value) return;
  2387.  
  2388.       var urlString = value + "\n" + window.content.document.title;
  2389.       var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
  2390.  
  2391.       aXferData.data = new TransferData();
  2392.       aXferData.data.addDataForFlavour("text/x-moz-url", urlString);
  2393.       aXferData.data.addDataForFlavour("text/unicode", value);
  2394.       aXferData.data.addDataForFlavour("text/html", htmlString);
  2395.  
  2396.       // we're copying the URL from the proxy icon, not moving
  2397.       // we specify all of them though, because d&d sucks and OS's
  2398.       // get confused if they don't get the one they want
  2399.       aDragAction.action =
  2400.         Components.interfaces.nsIDragService.DRAGDROP_ACTION_COPY |
  2401.         Components.interfaces.nsIDragService.DRAGDROP_ACTION_MOVE |
  2402.         Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
  2403.     }
  2404. }
  2405.  
  2406. var homeButtonObserver = {
  2407.   onDrop: function (aEvent, aXferData, aDragSession)
  2408.     {
  2409.       var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
  2410.       setTimeout(openHomeDialog, 0, url);
  2411.     },
  2412.  
  2413.   onDragOver: function (aEvent, aFlavour, aDragSession)
  2414.     {
  2415.       var statusTextFld = document.getElementById("statusbar-display");
  2416.       statusTextFld.label = gNavigatorBundle.getString("droponhomebutton");
  2417.       aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
  2418.     },
  2419.  
  2420.   onDragExit: function (aEvent, aDragSession)
  2421.     {
  2422.       var statusTextFld = document.getElementById("statusbar-display");
  2423.       statusTextFld.label = "";
  2424.     },
  2425.  
  2426.   getSupportedFlavours: function ()
  2427.     {
  2428.       var flavourSet = new FlavourSet();
  2429.       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2430.       flavourSet.appendFlavour("text/x-moz-url");
  2431.       flavourSet.appendFlavour("text/unicode");
  2432.       return flavourSet;
  2433.     }
  2434. }
  2435.  
  2436. function openHomeDialog(aURL)
  2437. {
  2438.   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  2439.   var promptTitle = gNavigatorBundle.getString("droponhometitle");
  2440.   var promptMsg   = gNavigatorBundle.getString("droponhomemsg");
  2441.   var pressedVal  = promptService.confirmEx(window, promptTitle, promptMsg,
  2442.                           (promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0) +
  2443.                           (promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1),
  2444.                           null, null, null, null, {value:0});
  2445.  
  2446.   if (pressedVal == 0) {
  2447.     try {
  2448.       var str = Components.classes["@mozilla.org/supports-string;1"]
  2449.                           .createInstance(Components.interfaces.nsISupportsString);
  2450.       str.data = aURL;
  2451.       gPrefService.setComplexValue("browser.startup.homepage",
  2452.                                    Components.interfaces.nsISupportsString, str);
  2453.       var homeButton = document.getElementById("home-button");
  2454.       homeButton.setAttribute("tooltiptext", aURL);
  2455.     } catch (ex) {
  2456.       dump("Failed to set the home page.\n"+ex+"\n");
  2457.     }
  2458.   }
  2459. }
  2460.  
  2461. var bookmarksButtonObserver = {
  2462.   onDrop: function (aEvent, aXferData, aDragSession)
  2463.   {
  2464.     var split = aXferData.data.split("\n");
  2465.     var url = split[0];
  2466.     if (url != aXferData.data) {  //do nothing if it's not a valid URL
  2467.       var dialogArgs = {
  2468.         name: split[1],
  2469.         url: url
  2470.       }
  2471. //@line 2822 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2472.       openDialog("chrome://browser/content/bookmarks/addBookmark2.xul", "",
  2473.                  BROWSER_ADD_BM_FEATURES, dialogArgs);
  2474. //@line 2827 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2475.     }
  2476.   },
  2477.  
  2478.   onDragOver: function (aEvent, aFlavour, aDragSession)
  2479.   {
  2480.     var statusTextFld = document.getElementById("statusbar-display");
  2481.     statusTextFld.label = gNavigatorBundle.getString("droponbookmarksbutton");
  2482.     aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
  2483.   },
  2484.  
  2485.   onDragExit: function (aEvent, aDragSession)
  2486.   {
  2487.     var statusTextFld = document.getElementById("statusbar-display");
  2488.     statusTextFld.label = "";
  2489.   },
  2490.  
  2491.   getSupportedFlavours: function ()
  2492.   {
  2493.     var flavourSet = new FlavourSet();
  2494.     flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2495.     flavourSet.appendFlavour("text/x-moz-url");
  2496.     flavourSet.appendFlavour("text/unicode");
  2497.     return flavourSet;
  2498.   }
  2499. }
  2500.  
  2501. var newTabButtonObserver = {
  2502.   onDragOver: function(aEvent, aFlavour, aDragSession)
  2503.     {
  2504.       var statusTextFld = document.getElementById("statusbar-display");
  2505.       statusTextFld.label = gNavigatorBundle.getString("droponnewtabbutton");
  2506.       aEvent.target.setAttribute("dragover", "true");
  2507.       return true;
  2508.     },
  2509.   onDragExit: function (aEvent, aDragSession)
  2510.     {
  2511.       var statusTextFld = document.getElementById("statusbar-display");
  2512.       statusTextFld.label = "";
  2513.       aEvent.target.removeAttribute("dragover");
  2514.     },
  2515.   onDrop: function (aEvent, aXferData, aDragSession)
  2516.     {
  2517.       var xferData = aXferData.data.split("\n");
  2518.       var draggedText = xferData[0] || xferData[1];
  2519.       var postData = {};
  2520.       var url = getShortcutOrURI(draggedText, postData);
  2521.       if (url) {
  2522.         getBrowser().dragDropSecurityCheck(aEvent, aDragSession, url);
  2523.         // allow third-party services to fixup this URL
  2524.         openNewTabWith(url, null, postData.value, aEvent, true);
  2525.       }
  2526.     },
  2527.   getSupportedFlavours: function ()
  2528.     {
  2529.       var flavourSet = new FlavourSet();
  2530.       flavourSet.appendFlavour("text/unicode");
  2531.       flavourSet.appendFlavour("text/x-moz-url");
  2532.       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2533.       return flavourSet;
  2534.     }
  2535. }
  2536.  
  2537. var newWindowButtonObserver = {
  2538.   onDragOver: function(aEvent, aFlavour, aDragSession)
  2539.     {
  2540.       var statusTextFld = document.getElementById("statusbar-display");
  2541.       statusTextFld.label = gNavigatorBundle.getString("droponnewwindowbutton");
  2542.       aEvent.target.setAttribute("dragover", "true");
  2543.       return true;
  2544.     },
  2545.   onDragExit: function (aEvent, aDragSession)
  2546.     {
  2547.       var statusTextFld = document.getElementById("statusbar-display");
  2548.       statusTextFld.label = "";
  2549.       aEvent.target.removeAttribute("dragover");
  2550.     },
  2551.   onDrop: function (aEvent, aXferData, aDragSession)
  2552.     {
  2553.       var xferData = aXferData.data.split("\n");
  2554.       var draggedText = xferData[0] || xferData[1];
  2555.       var postData = {};
  2556.       var url = getShortcutOrURI(draggedText, postData);
  2557.       if (url) {
  2558.         getBrowser().dragDropSecurityCheck(aEvent, aDragSession, url);
  2559.         // allow third-party services to fixup this URL
  2560.         openNewWindowWith(url, null, postData.value, true);
  2561.       }
  2562.     },
  2563.   getSupportedFlavours: function ()
  2564.     {
  2565.       var flavourSet = new FlavourSet();
  2566.       flavourSet.appendFlavour("text/unicode");
  2567.       flavourSet.appendFlavour("text/x-moz-url");
  2568.       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2569.       return flavourSet;
  2570.     }
  2571. }
  2572.  
  2573. var goButtonObserver = {
  2574.   onDragOver: function(aEvent, aFlavour, aDragSession)
  2575.     {
  2576.       var statusTextFld = document.getElementById("statusbar-display");
  2577.       statusTextFld.label = gNavigatorBundle.getString("dropongobutton");
  2578.       aEvent.target.setAttribute("dragover", "true");
  2579.       return true;
  2580.     },
  2581.   onDragExit: function (aEvent, aDragSession)
  2582.     {
  2583.       var statusTextFld = document.getElementById("statusbar-display");
  2584.       statusTextFld.label = "";
  2585.       aEvent.target.removeAttribute("dragover");
  2586.     },
  2587.   onDrop: function (aEvent, aXferData, aDragSession)
  2588.     {
  2589.       var xferData = aXferData.data.split("\n");
  2590.       var draggedText = xferData[0] || xferData[1];
  2591.       var postData = {};
  2592.       var url = getShortcutOrURI(draggedText, postData);
  2593.       try {
  2594.         getBrowser().dragDropSecurityCheck(aEvent, aDragSession, url);
  2595.  
  2596.         const nsIScriptSecMan = Components.interfaces.nsIScriptSecurityManager;
  2597.         urlSecurityCheck(url, gBrowser.currentURI.spec,
  2598.                          nsIScriptSecMan.DISALLOW_SCRIPT_OR_DATA);
  2599.         loadURI(url, null, postData.value, true);
  2600.       } catch (ex) {}
  2601.     },
  2602.   getSupportedFlavours: function ()
  2603.     {
  2604.       var flavourSet = new FlavourSet();
  2605.       flavourSet.appendFlavour("text/unicode");
  2606.       flavourSet.appendFlavour("text/x-moz-url");
  2607.       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  2608.       return flavourSet;
  2609.     }
  2610. }
  2611.  
  2612. var DownloadsButtonDNDObserver = {
  2613.   /////////////////////////////////////////////////////////////////////////////
  2614.   // nsDragAndDrop
  2615.   onDragOver: function (aEvent, aFlavour, aDragSession)
  2616.   {
  2617.     var statusTextFld = document.getElementById("statusbar-display");
  2618.     statusTextFld.label = gNavigatorBundle.getString("dropondownloadsbutton");
  2619.     aDragSession.canDrop = (aFlavour.contentType == "text/x-moz-url" ||
  2620.                             aFlavour.contentType == "text/unicode");
  2621.   },
  2622.  
  2623.   onDragExit: function (aEvent, aDragSession)
  2624.   {
  2625.     var statusTextFld = document.getElementById("statusbar-display");
  2626.     statusTextFld.label = "";
  2627.   },
  2628.  
  2629.   onDrop: function (aEvent, aXferData, aDragSession)
  2630.   {
  2631.     var split = aXferData.data.split("\n");
  2632.     var url = split[0];
  2633.     if (url != aXferData.data) {  //do nothing, not a valid URL
  2634.       getBrowser().dragDropSecurityCheck(aEvent, aDragSession, url);
  2635.  
  2636.       var name = split[1];
  2637.       saveURL(url, name, null, true, true);
  2638.     }
  2639.   },
  2640.   getSupportedFlavours: function ()
  2641.   {
  2642.     var flavourSet = new FlavourSet();
  2643.     flavourSet.appendFlavour("text/x-moz-url");
  2644.     flavourSet.appendFlavour("text/unicode");
  2645.     return flavourSet;
  2646.   }
  2647. }
  2648.  
  2649. const BrowserSearch = {
  2650.  
  2651.   /**
  2652.    * Initialize the BrowserSearch
  2653.    */
  2654.   init: function() {
  2655.     gBrowser.addEventListener("DOMLinkAdded", 
  2656.                               function (event) { BrowserSearch.onLinkAdded(event); }, 
  2657.                               false);
  2658.   },
  2659.  
  2660.   /**
  2661.    * A new <link> tag has been discovered - check to see if it advertises
  2662.    * a OpenSearch engine.
  2663.    */
  2664.   onLinkAdded: function(event) {
  2665.     // XXX this event listener can/should probably be combined with the onLinkAdded
  2666.     // listener in tabbrowser.xml.  See comments in FeedHandler.onLinkAdded().
  2667.     const target = event.target;
  2668.     var etype = target.type;
  2669.     const searchRelRegex = /(^|\s)search($|\s)/i;
  2670.     const searchHrefRegex = /^(https?|ftp):\/\//i;
  2671.  
  2672.     if (!etype)
  2673.       return;
  2674.  
  2675.     // Bug 349431: If the engine has no suggested title, ignore it rather
  2676.     // than trying to find an alternative.
  2677.     if (!target.title)
  2678.       return;
  2679.  
  2680.     if (etype == "application/opensearchdescription+xml" &&
  2681.         searchRelRegex.test(target.rel) && searchHrefRegex.test(target.href))
  2682.     {
  2683.       const targetDoc = target.ownerDocument;
  2684.       // Set the attribute of the (first) search-engine button.
  2685.       var searchButton = document.getAnonymousElementByAttribute(this.getSearchBar(),
  2686.                                   "anonid", "searchbar-engine-button");
  2687.       if (searchButton) {
  2688.         var browser = gBrowser.getBrowserForDocument(targetDoc);
  2689.          // Append the URI and an appropriate title to the browser data.
  2690.         var iconURL = null;
  2691.         if (gBrowser.shouldLoadFavIcon(browser.currentURI))
  2692.           iconURL = browser.currentURI.prePath + "/favicon.ico";
  2693.  
  2694.         var hidden = false;
  2695.         // If this engine (identified by title) is already in the list, add it
  2696.         // to the list of hidden engines rather than to the main list.
  2697.         // XXX This will need to be changed when engines are identified by URL;
  2698.         // see bug 335102.
  2699.         var searchService =
  2700.         Components.classes["@mozilla.org/browser/search-service;1"]
  2701.                   .getService(Components.interfaces.nsIBrowserSearchService);
  2702.         if (searchService.getEngineByName(target.title))
  2703.            hidden = true;
  2704.  
  2705.         var engines = [];
  2706.         if (hidden) {
  2707.           if (browser.hiddenEngines)
  2708.             engines = browser.hiddenEngines;
  2709.         }
  2710.         else {
  2711.           if (browser.engines)
  2712.             engines = browser.engines;
  2713.         }
  2714.  
  2715.         engines.push({ uri: target.href,
  2716.                        title: target.title,
  2717.                        icon: iconURL });
  2718.  
  2719.         if (hidden) {
  2720.           browser.hiddenEngines = engines;
  2721.         }
  2722.         else {
  2723.           browser.engines = engines;
  2724.           if (browser == gBrowser || browser == gBrowser.mCurrentBrowser)
  2725.             this.updateSearchButton();
  2726.         }
  2727.         
  2728.         if (browser.engines && browser.engines.length > 0) {
  2729.           var message = flockGetString("search/search",
  2730.                                     "flock.search.engine.discovered");
  2731.           var notificationBox = gBrowser.getNotificationBox(browser);
  2732.           var notification = notificationBox.getNotificationWithValue("search-discovered");
  2733.           if (!notification) {
  2734.             var links = [{
  2735.               label: flockGetString("favorites/favorites",
  2736.                                     "flock.favs.overlay.show-me-how"),
  2737.               callback: function() {  
  2738.                 $('favoritesSearchButton').click();
  2739.                  var method = "flashForDiscover("+ 1 +",'favoritesSearchButton',$('favoritesSearchButton'));";  
  2740.                   setTimeout(method, 500);
  2741.                  }
  2742.             }];
  2743.             notificationBox.appendUniqueNotification(message, "search-discovered",null, notificationBox.FLOCK_PRIORITY_LOW, null,  links, getWebNavigation().currentURI.host);
  2744.           }
  2745.         }
  2746.         
  2747.       }
  2748.     }
  2749.   },
  2750.  
  2751.   /**
  2752.    * Update the browser UI to show whether or not additional engines are 
  2753.    * available when a page is loaded or the user switches tabs to a page that 
  2754.    * has search engines. 
  2755.    */
  2756.   updateSearchButton: function() {
  2757.     // Note: we want the button to light up if there are installable search
  2758.     // engines on the page, regardless of whether they are already installed.
  2759.     // Already installed engines will show up as starred, disabled menu items,
  2760.     // so there will be no danger of the user re-installing.
  2761.     var numEngines = 0;
  2762.     var engTypes = ["engines", "hiddenEngines"];
  2763.     for (var e in engTypes) {
  2764.       var engines = gBrowser.mCurrentBrowser[engTypes[e]];
  2765.       if (engines) { numEngines += engines.length; }
  2766.     }
  2767.     
  2768.     var searchBtn = $("favoritesSearchButton");
  2769.     if (numEngines == 0) {
  2770.       searchBtn.setAttribute("disabled", "true");
  2771.       searchBtn.setAttribute("tooltiptext", flockGetString("search/search",
  2772.                                                   "flock.search.button.off.tip"));
  2773.     } else {
  2774.       searchBtn.removeAttribute("disabled");
  2775.       searchBtn.setAttribute("tooltiptext", flockGetString("search/search",
  2776.                                                   "flock.search.button.on.tip"));
  2777.     }    
  2778.     /*
  2779.     var searchButton = document.getAnonymousElementByAttribute(this.getSearchBar(),
  2780.                                 "anonid", "searchbar-engine-button");
  2781.     if (!searchButton)
  2782.       return;
  2783.     var engines = gBrowser.mCurrentBrowser.engines;
  2784.     if (!engines || engines.length == 0) {
  2785.       if (searchButton.hasAttribute("addengines"))
  2786.         searchButton.removeAttribute("addengines");
  2787.     }
  2788.     else {
  2789.       searchButton.setAttribute("addengines", "true");
  2790.     }
  2791.     */
  2792.   },
  2793.  
  2794.   /**
  2795.    * Gives focus to the search bar, if it is present on the toolbar, or loads
  2796.    * the default engine's search form otherwise. For Mac, opens a new window
  2797.    * or focuses an existing window, if necessary.
  2798.    */
  2799.   webSearch: function BrowserSearch_webSearch() {
  2800. //@line 3175 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  2801.     var searchBar = this.getSearchBar();
  2802.     if (searchBar) {
  2803.       searchBar.select();
  2804.       searchBar.focus();
  2805.     } else {
  2806.       var ss = Cc["@mozilla.org/browser/search-service;1"].
  2807.                getService(Ci.nsIBrowserSearchService);
  2808.       var searchForm = ss.defaultEngine.searchForm;
  2809.       loadURI(searchForm, null, null, false);
  2810.     }
  2811.   },
  2812.  
  2813.   /**
  2814.    * Loads a search results page, given a set of search terms. Uses the current
  2815.    * engine if the search bar is visible, or the default engine otherwise.
  2816.    *
  2817.    * @param searchText
  2818.    *        The search terms to use for the search.
  2819.    *
  2820.    * @param useNewTab
  2821.    *        Boolean indicating whether or not the search should load in a new
  2822.    *        tab.
  2823.    */
  2824.   loadSearch: function BrowserSearch_search(searchText, useNewTab) {
  2825.     var ss = Cc["@mozilla.org/browser/search-service;1"].
  2826.              getService(Ci.nsIBrowserSearchService);
  2827.     var engine;
  2828.   
  2829.     // If the search bar is visible, use the current engine, otherwise, fall
  2830.     // back to the default engine.
  2831.     if (this.getSearchBar())
  2832.       engine = ss.currentEngine;
  2833.     else
  2834.       engine = ss.defaultEngine;
  2835.   
  2836.     var submission = engine.getSubmission(searchText, null); // HTML response
  2837.  
  2838.     // getSubmission can return null if the engine doesn't have a URL
  2839.     // with a text/html response type.  This is unlikely (since
  2840.     // SearchService._addEngineToStore() should fail for such an engine),
  2841.     // but let's be on the safe side.
  2842.     if (!submission)
  2843.       return;
  2844.   
  2845.     if (useNewTab) {
  2846.       getBrowser().loadOneTab(submission.uri.spec, null, null,
  2847.                               submission.postData, null, false);
  2848.     } else
  2849.       loadURI(submission.uri.spec, null, submission.postData, false);
  2850.   },
  2851.  
  2852.   /**
  2853.    * Returns the search bar element if it is present in the toolbar and not
  2854.    * hidden, null otherwise.
  2855.    */
  2856.   getSearchBar: function BrowserSearch_getSearchBar() {
  2857.     var searchBar = document.getElementById("searchbar");
  2858.     if (searchBar && searchBar.parentNode) {
  2859.       var style = window.getComputedStyle(searchBar.parentNode, null);
  2860.       if (style.visibility == "visible" && style.display != "none")
  2861.         return searchBar;
  2862.     }
  2863.     return null;
  2864.   },
  2865.  
  2866.   loadAddEngines: function BrowserSearch_loadAddEngines() {
  2867.     var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
  2868.     var where = newWindowPref == 3 ? "tab" : "window";
  2869.     var regionBundle = document.getElementById("bundle_browser_region");
  2870.     var searchEnginesURL = formatURL("browser.search.searchEnginesURL", true);
  2871.     openUILinkIn(searchEnginesURL, where);
  2872.   }
  2873. }
  2874.  
  2875. function FillHistoryMenu(aParent, aMenu, aInsertBefore)
  2876.   {
  2877.     // Remove old entries if any
  2878.     deleteHistoryItems(aParent);
  2879.  
  2880.     var webNav = getWebNavigation();
  2881.     if (!webNav) {
  2882.       // This is always the case for non-browser windows (and the hidden window)
  2883.       // on OS X
  2884.       return true;
  2885.     }
  2886.     var sessionHistory = webNav.sessionHistory;
  2887.  
  2888.     var count = sessionHistory.count;
  2889.     var index = sessionHistory.index;
  2890.     var end;
  2891.     var j;
  2892.     var entry;
  2893.  
  2894.     switch (aMenu)
  2895.       {
  2896.         case "back":
  2897.           end = (index > MAX_HISTORY_MENU_ITEMS) ? index - MAX_HISTORY_MENU_ITEMS : 0;
  2898.           if ((index - 1) < end) return false;
  2899.           for (j = index - 1; j >= end; j--)
  2900.             {
  2901.               entry = sessionHistory.getEntryAtIndex(j, false);
  2902.               if (entry)
  2903.                 createMenuItem(aParent, j, entry.title);
  2904.             }
  2905.           break;
  2906.         case "forward":
  2907.           end  = ((count-index) > MAX_HISTORY_MENU_ITEMS) ? index + MAX_HISTORY_MENU_ITEMS : count - 1;
  2908.           if ((index + 1) > end) return false;
  2909.           for (j = index + 1; j <= end; j++)
  2910.             {
  2911.               entry = sessionHistory.getEntryAtIndex(j, false);
  2912.               if (entry)
  2913.                 createMenuItem(aParent, j, entry.title);
  2914.             }
  2915.           break;
  2916.         case "history":
  2917.           aInsertBefore.hidden = (count == 0);
  2918.           end = count > MAX_HISTORY_MENU_ITEMS ? count - MAX_HISTORY_MENU_ITEMS : 0;
  2919.           for (j = count - 1; j >= end; j--)
  2920.             {
  2921.               entry = sessionHistory.getEntryAtIndex(j, false);
  2922.               if (entry)
  2923.                 createRadioMenuItem(aParent,
  2924.                                     j,
  2925.                                     entry.title,
  2926.                                     entry.URI ? entry.URI.spec : null,
  2927.                                     j==index,
  2928.                                     aInsertBefore);
  2929.             }
  2930.           break;
  2931.       }
  2932.  
  2933.     // enable/disable RCT sub menu
  2934.     HistoryMenu.toggleRecentlyClosedTabs();
  2935.  
  2936.     return true;
  2937.   }
  2938.  
  2939. function addToUrlbarHistory(aUrlToAdd)
  2940. {
  2941.   if (!aUrlToAdd)
  2942.      return;
  2943.   if (aUrlToAdd.search(/[\x00-\x1F]/) != -1) // don't store bad URLs
  2944.      return;
  2945.  
  2946.   if (!gGlobalHistory)
  2947.     gGlobalHistory = Components.classes["@mozilla.org/browser/global-history;2"]
  2948.                                .getService(Components.interfaces.nsIBrowserHistory);
  2949.  
  2950.   if (!gURIFixup)
  2951.     gURIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  2952.                           .getService(Components.interfaces.nsIURIFixup);
  2953.    try {
  2954.      if (aUrlToAdd.indexOf(" ") == -1) {
  2955.        var fixedUpURI = gURIFixup.createFixupURI(aUrlToAdd, 0);
  2956.        gGlobalHistory.markPageAsTyped(fixedUpURI);
  2957.      }
  2958.    }
  2959.    catch(ex) {
  2960.    }
  2961. }
  2962.  
  2963. function createMenuItem( aParent, aIndex, aLabel)
  2964.   {
  2965.     var menuitem = document.createElement( "menuitem" );
  2966.     menuitem.setAttribute( "label", aLabel );
  2967.     menuitem.setAttribute( "index", aIndex );
  2968.     aParent.appendChild( menuitem );
  2969.   }
  2970.  
  2971. function createRadioMenuItem( aParent, aIndex, aLabel, aStatusText, aChecked, aInsertBefore)
  2972.   {
  2973.     var menuitem = document.createElement( "menuitem" );
  2974.     menuitem.setAttribute( "type", "radio" );
  2975.     menuitem.setAttribute( "label", aLabel );
  2976.     menuitem.setAttribute( "index", aIndex );
  2977.     menuitem.setAttribute( "statustext", aStatusText );
  2978.     if (aChecked==true)
  2979.       menuitem.setAttribute( "checked", "true" );
  2980.     if (aInsertBefore)
  2981.       aParent.insertBefore( menuitem, aInsertBefore );
  2982.     else
  2983.       aParent.appendChild( menuitem );
  2984.   }
  2985.  
  2986. function deleteHistoryItems(aParent)
  2987. {
  2988.   var children = aParent.childNodes;
  2989.   for (var i = children.length - 1; i >= 0; --i)
  2990.     {
  2991.       var index = children[i].getAttribute("index");
  2992.       if (index)
  2993.         aParent.removeChild(children[i]);
  2994.     }
  2995. }
  2996.  
  2997. function toJavaScriptConsole()
  2998. {
  2999.   toOpenWindowByType("global:console", "chrome://global/content/console.xul");
  3000. }
  3001.  
  3002. function toOpenWindowByType(inType, uri, features)
  3003. {
  3004.   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  3005.   var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  3006.   var topWindow = windowManagerInterface.getMostRecentWindow(inType);
  3007.  
  3008.   if (topWindow)
  3009.     topWindow.focus();
  3010.   else if (features)
  3011.     window.open(uri, "_blank", features);
  3012.   else
  3013.     window.open(uri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
  3014. }
  3015.  
  3016. function toOpenDialogByTypeAndUrl(inType, relatedUrl, windowUri, features, extraArgument)
  3017. {
  3018.   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  3019.   var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  3020.   var windows = windowManagerInterface.getEnumerator(inType);
  3021.  
  3022.   // Check for windows matching the url
  3023.   while (windows.hasMoreElements()) {
  3024.     var currentWindow = windows.getNext();
  3025.     if (currentWindow.document.documentElement.getAttribute("relatedUrl") == relatedUrl) {
  3026.         currentWindow.focus();
  3027.         return;
  3028.     }
  3029.   }
  3030.  
  3031.   // We didn't find a matching window, so open a new one.
  3032.   if (features)
  3033.     window.openDialog(windowUri, "_blank", features, extraArgument);
  3034.   else
  3035.     window.openDialog(windowUri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar", extraArgument);
  3036. }
  3037.  
  3038. function OpenBrowserWindow()
  3039. {
  3040.   var charsetArg = new String();
  3041.   var handler = Components.classes["@mozilla.org/browser/clh;1"]
  3042.                           .getService(Components.interfaces.nsIBrowserHandler);
  3043.   var defaultArgs = handler.defaultArgs;
  3044.   var wintype = document.documentElement.getAttribute('windowtype');
  3045.  
  3046.   // if and only if the current window is a browser window and it has a document with a character
  3047.   // set, then extract the current charset menu setting from the current document and use it to
  3048.   // initialize the new browser window...
  3049.   var win;
  3050.   if (window && (wintype == "navigator:browser") && window.content && window.content.document)
  3051.   {
  3052.     var DocCharset = window.content.document.characterSet;
  3053.     charsetArg = "charset="+DocCharset;
  3054.  
  3055.     //we should "inherit" the charset menu setting in a new window
  3056.     win = window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no", defaultArgs, charsetArg);
  3057.   }
  3058.   else // forget about the charset information.
  3059.   {
  3060.     win = window.openDialog("chrome://browser/content/", "_blank", "chrome,all,dialog=no", defaultArgs);
  3061.   }
  3062.  
  3063.   return win;
  3064. }
  3065.  
  3066. function BrowserCustomizeToolbar()
  3067. {
  3068.   // Disable the toolbar context menu items
  3069.   var menubar = document.getElementById("main-menubar");
  3070.   for (var i = 0; i < menubar.childNodes.length; ++i)
  3071.     menubar.childNodes[i].setAttribute("disabled", true);
  3072.  
  3073.   var cmd = document.getElementById("cmd_CustomizeToolbars");
  3074.   cmd.setAttribute("disabled", "true");
  3075.  
  3076. //@line 3469 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3077.   window.openDialog("chrome://global/content/customizeToolbar.xul",
  3078.                     "CustomizeToolbar",
  3079.                     "chrome,all,dependent",
  3080.                     document.getElementById("navigator-toolbox"));
  3081. //@line 3474 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3082. }
  3083.  
  3084. function BrowserToolboxCustomizeDone(aToolboxChanged)
  3085. {
  3086. //@line 3481 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3087.  
  3088.   // Update global UI elements that may have been added or removed
  3089.   if (aToolboxChanged) {
  3090.     gURLBar = document.getElementById("urlbar");
  3091.     gURLBarContainer = document.getElementById("urlbar-container");
  3092.     if (gURLBar)
  3093.       gURLBar.clickSelectsAll = gClickSelectsAll;
  3094.     gProxyButton = document.getElementById("page-proxy-button");
  3095.     gProxyFavIcon = document.getElementById("page-proxy-favicon");
  3096.     gProxyDeck = document.getElementById("page-proxy-deck");
  3097.     gHomeButton.updateTooltip();
  3098.     window.XULBrowserWindow.init();
  3099.   }
  3100.  
  3101.   // Update the urlbar
  3102.   var url = getWebNavigation().currentURI.spec;
  3103.   if (gURLBar) {
  3104.     gURLBar.value = url == "about:blank" ? "" : url;
  3105.     SetPageProxyState("valid");
  3106.     XULBrowserWindow.asyncUpdateUI();
  3107.     gGoButtonPrefListener.toggleGoButton();
  3108.   }
  3109.  
  3110.   // Re-enable parts of the UI we disabled during the dialog
  3111.   var menubar = document.getElementById("main-menubar");
  3112.   for (var i = 0; i < menubar.childNodes.length; ++i)
  3113.     menubar.childNodes[i].setAttribute("disabled", false);
  3114.   var cmd = document.getElementById("cmd_CustomizeToolbars");
  3115.   cmd.removeAttribute("disabled");
  3116.  
  3117.   // XXXmano bug 287105: wallpaper to bug 309953,
  3118.   // the reload button isn't in sync with the reload command.
  3119.   var reloadButton = document.getElementById("reload-button");
  3120.   if (reloadButton) {
  3121.     reloadButton.disabled =
  3122.       document.getElementById("Browser:Reload").getAttribute("disabled") == "true";
  3123.   }
  3124.  
  3125. //@line 3524 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3126.  
  3127. //@line 3526 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3128.   // fix up the personal toolbar folder
  3129.   var bt = document.getElementById("bookmarks-ptf");
  3130.   if (bt) {
  3131.     var btf = BMSVC.getBookmarksToolbarFolder().Value;
  3132.     var btchevron = document.getElementById("bookmarks-chevron");
  3133.     bt.ref = btf;
  3134.     btchevron.ref = btf;
  3135.     // no uniqueness is guaranteed, so we have to remove first
  3136.     try {
  3137.       bt.database.RemoveObserver(BookmarksToolbarRDFObserver);
  3138.     } catch (ex) {
  3139.       // ignore
  3140.     }
  3141.     bt.database.AddObserver(BookmarksToolbarRDFObserver);
  3142.     bt.builder.rebuild();
  3143.     btchevron.builder.rebuild();
  3144.  
  3145.     // fake a resize; this function takes care of flowing bookmarks
  3146.     // from the bar to the overflow item
  3147.     BookmarksToolbar.resizeFunc(null);
  3148.   }
  3149. //@line 3551 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3150.  
  3151. //@line 3553 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3152.   // XXX Shouldn't have to do this, but I do
  3153.   window.focus();
  3154. //@line 3556 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3155. }
  3156.  
  3157. var FullScreen =
  3158. {
  3159.   toggle: function()
  3160.   {
  3161.     // show/hide all menubars, toolbars, and statusbars (except the full screen toolbar)
  3162.     this.showXULChrome("toolbar", window.fullScreen);
  3163.     this.showXULChrome("statusbar", window.fullScreen);
  3164.     document.getElementById("fullScreenItem").setAttribute("checked", !window.fullScreen);
  3165.   },
  3166.  
  3167.   showXULChrome: function(aTag, aShow)
  3168.   {
  3169.     var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  3170.     var els = document.getElementsByTagNameNS(XULNS, aTag);
  3171.  
  3172.     var i, savedMode, savedIconSize;
  3173.     for (i = 0; i < els.length; ++i) {
  3174.       // XXX don't interfere with previously collapsed toolbars
  3175.       if (els[i].getAttribute("fullscreentoolbar") == "true") {
  3176.         if (!aShow) {
  3177.           var toolbarMode = els[i].getAttribute("mode");
  3178.           var iconSize = els[i].getAttribute("iconsize");
  3179.           var contextMenu = els[i].getAttribute("context");
  3180.  
  3181.           if (toolbarMode != "text") {
  3182.             els[i].setAttribute("saved-mode", toolbarMode);
  3183.             els[i].setAttribute("saved-iconsize", iconSize);
  3184.             els[i].setAttribute("mode", "icons");
  3185.             els[i].setAttribute("iconsize", "small");
  3186.           }
  3187.  
  3188.           // XXX See bug 202978: we disable the context menu
  3189.           // to prevent customization while in fullscreen, which
  3190.           // causes menu breakage.
  3191.           els[i].setAttribute("saved-context", contextMenu);
  3192.           els[i].removeAttribute("context");
  3193.         }
  3194.         else {
  3195.           if (els[i].hasAttribute("saved-mode")) {
  3196.             savedMode = els[i].getAttribute("saved-mode");
  3197.             els[i].setAttribute("mode", savedMode);
  3198.             els[i].removeAttribute("saved-mode");
  3199.           }
  3200.  
  3201.           if (els[i].hasAttribute("saved-iconsize")) {
  3202.             savedIconSize = els[i].getAttribute("saved-iconsize");
  3203.             els[i].setAttribute("iconsize", savedIconSize);
  3204.             els[i].removeAttribute("saved-iconsize");
  3205.           }
  3206.  
  3207.           // XXX see above.
  3208.           if (els[i].hasAttribute("saved-context")) {
  3209.             var savedContext = els[i].getAttribute("saved-context");
  3210.             els[i].setAttribute("context", savedContext);
  3211.             els[i].removeAttribute("saved-context");
  3212.           }
  3213.         }
  3214.       } else {
  3215.         // use moz-collapsed so it doesn't persist hidden/collapsed,
  3216.         // so that new windows don't have missing toolbars
  3217.         if (aShow)
  3218.           els[i].removeAttribute("moz-collapsed");
  3219.         else
  3220.           els[i].setAttribute("moz-collapsed", "true");
  3221.       }
  3222.     }
  3223. //@line 3625 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3224.     var controls = document.getElementsByAttribute("fullscreencontrol", "true");
  3225.     for (i = 0; i < controls.length; ++i)
  3226.       controls[i].hidden = aShow;
  3227. //@line 3629 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3228.  
  3229.     // XXXvladimir this was a fix for bug 174174, but I don't think it's necessary
  3230.     // any more?
  3231.     var toolbox = document.getElementById("navigator-toolbox");
  3232.     if (!aShow) {
  3233.       var toolboxMode = toolbox.getAttribute("mode");
  3234.       var toolboxIconSize = toolbox.getAttribute("iconsize");
  3235.       if (toolboxMode != "text") {
  3236.         toolbox.setAttribute("saved-mode", toolboxMode);
  3237.         toolbox.setAttribute("saved-iconsize", toolboxIconSize);
  3238.         toolbox.setAttribute("mode", "icons");
  3239.         toolbox.setAttribute("iconsize", "small");
  3240.       }
  3241.       else {
  3242.         if (toolbox.hasAttribute("saved-mode")) {
  3243.           savedMode = toolbox.getAttribute("saved-mode");
  3244.           toolbox.setAttribute("mode", savedMode);
  3245.           toolbox.removeAttribute("saved-mode");
  3246.         }
  3247.  
  3248.         if (toolbox.hasAttribute("saved-iconsize")) {
  3249.           savedIconSize = toolbox.getAttribute("saved-iconsize");
  3250.           toolbox.setAttribute("iconsize", savedIconSize);
  3251.           toolbox.removeAttribute("saved-iconsize");
  3252.         }
  3253.       }
  3254.     }
  3255.   }
  3256. };
  3257.  
  3258. function FlockDocumentReady(aEvent)
  3259. {
  3260.   var myDoc = aEvent.target;
  3261.   var urlStr = myDoc.location;
  3262.   if (urlStr && ((urlStr+"").indexOf("http") == 0)) {
  3263.     var fdrEvent = gProfiler.profileEventStart("f-d-r");
  3264.     dump("Browser.js - FlockDocumentReady aEvent is " + aEvent + "\n");
  3265.     dump("Browser.js - FlockDocumentReady aEvent.target is " + aEvent.target + "\n");
  3266.     var observerService = Components.classes["@mozilla.org/observer-service;1"]
  3267.                                     .getService(Components.interfaces.nsIObserverService);
  3268.     
  3269.     observerService.notifyObservers(myDoc, "FlockDocumentReady", urlStr);
  3270.     dump("Browser.js - Sent FlockDocumentReady Event\n");     
  3271.     gProfiler.profileEventEnd(fdrEvent, urlStr);
  3272.   }
  3273. }
  3274.  
  3275.  
  3276. function nsBrowserStatusHandler()
  3277. {
  3278.   this.init();
  3279. }
  3280.  
  3281. nsBrowserStatusHandler.prototype =
  3282. {
  3283.   // Stored Status, Link and Loading values
  3284.   status : "",
  3285.   defaultStatus : "",
  3286.   jsStatus : "",
  3287.   jsDefaultStatus : "",
  3288.   overLink : "",
  3289.   startTime : 0,
  3290.   statusText: "",
  3291.   lastURI: null,
  3292.  
  3293.   statusTimeoutInEffect : false,
  3294.  
  3295.   QueryInterface : function(aIID)
  3296.   {
  3297.     if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  3298.         aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  3299.         aIID.equals(Components.interfaces.nsIXULBrowserWindow) ||
  3300.         aIID.equals(Components.interfaces.nsISupports))
  3301.       return this;
  3302.     throw Components.results.NS_NOINTERFACE;
  3303.   },
  3304.  
  3305.   init : function()
  3306.   {
  3307.     this.throbberElement        = document.getElementById("navigator-throbber");
  3308.     this.statusMeter            = document.getElementById("statusbar-icon");
  3309.     this.stopCommand            = document.getElementById("Browser:Stop");
  3310.     this.reloadCommand          = document.getElementById("Browser:Reload");
  3311.     this.reloadSkipCacheCommand = document.getElementById("Browser:ReloadSkipCache");
  3312.     this.statusTextField        = document.getElementById("statusbar-display");
  3313.     this.securityButton         = document.getElementById("security-button");
  3314.     this.urlBar                 = document.getElementById("urlbar");
  3315.     this.isImage                = document.getElementById("isImage");
  3316.  
  3317.     // Initialize the security button's state and tooltip text
  3318.     var securityUI = getBrowser().securityUI;
  3319.     this.onSecurityChange(null, null, securityUI.state);
  3320.   },
  3321.  
  3322.   destroy : function()
  3323.   {
  3324.     // XXXjag to avoid leaks :-/, see bug 60729
  3325.     this.throbberElement        = null;
  3326.     this.statusMeter            = null;
  3327.     this.stopCommand            = null;
  3328.     this.reloadCommand          = null;
  3329.     this.reloadSkipCacheCommand = null;
  3330.     this.statusTextField        = null;
  3331.     this.securityButton         = null;
  3332.     this.urlBar                 = null;
  3333.     this.statusText             = null;
  3334.     this.lastURI                = null;
  3335.   },
  3336.  
  3337.   setJSStatus : function(status)
  3338.   {
  3339.     this.jsStatus = status;
  3340.     this.updateStatusField();
  3341.   },
  3342.  
  3343.   setJSDefaultStatus : function(status)
  3344.   {
  3345.     this.jsDefaultStatus = status;
  3346.     this.updateStatusField();
  3347.   },
  3348.  
  3349.   setDefaultStatus : function(status)
  3350.   {
  3351.     this.defaultStatus = status;
  3352.     this.updateStatusField();
  3353.   },
  3354.  
  3355.   setOverLink : function(link, b)
  3356.   {
  3357.     this.overLink = link;
  3358.     this.updateStatusField();
  3359.   },
  3360.  
  3361.   updateStatusField : function()
  3362.   {
  3363.     var text = this.overLink || this.status || this.jsStatus || this.jsDefaultStatus || this.defaultStatus;
  3364.  
  3365.     // check the current value so we don't trigger an attribute change
  3366.     // and cause needless (slow!) UI updates
  3367.     if (this.statusText != text) {
  3368.       this.statusTextField.label = text;
  3369.       this.statusText = text;
  3370.     }
  3371.   },
  3372.   
  3373.   mimeTypeIsTextBased : function(contentType)
  3374.   {
  3375.     return /^text\/|\+xml$/.test(contentType) ||
  3376.            contentType == "application/x-javascript" ||
  3377.            contentType == "application/xml" ||
  3378.            contentType == "mozilla.application/cached-xul";
  3379.   },
  3380.  
  3381.   onLinkIconAvailable : function(aBrowser)
  3382.   {
  3383.     if (gProxyFavIcon &&
  3384.         gBrowser.mCurrentBrowser == aBrowser &&
  3385.         gBrowser.userTypedValue === null)
  3386.     {
  3387.       // update the favicon in the URL bar
  3388.       PageProxySetIcon(aBrowser.mIconURL);
  3389.  
  3390. //@line 3801 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3391.     }
  3392.   },
  3393.  
  3394.   onProgressChange : function (aWebProgress, aRequest,
  3395.                                aCurSelfProgress, aMaxSelfProgress,
  3396.                                aCurTotalProgress, aMaxTotalProgress)
  3397.   {
  3398.     if (aMaxTotalProgress > 0) {
  3399.       // This is highly optimized.  Don't touch this code unless
  3400.       // you are intimately familiar with the cost of setting
  3401.       // attrs on XUL elements. -- hyatt
  3402.       var percentage = (aCurTotalProgress * 100) / aMaxTotalProgress;
  3403.       this.statusMeter.value = percentage;
  3404.     }
  3405.   },
  3406.  
  3407.   onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  3408.   {
  3409.     const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  3410.     const nsIChannel = Components.interfaces.nsIChannel;
  3411.     if (aStateFlags & nsIWebProgressListener.STATE_START) {
  3412.         // This (thanks to the filter) is a network start or the first
  3413.         // stray request (the first request outside of the document load),
  3414.         // initialize the throbber and his friends.
  3415.  
  3416.         // Call start document load listeners (only if this is a network load)
  3417.         if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK &&
  3418.             aRequest && aWebProgress.DOMWindow == content)
  3419.           this.startDocumentLoad(aRequest);
  3420.  
  3421.         if (this.throbberElement) {
  3422.           // Turn the throbber on.
  3423.           this.throbberElement.setAttribute("busy", "true");
  3424.         }
  3425.  
  3426.         // Turn the status meter on.
  3427.         this.statusMeter.value = 0;  // be sure to clear the progress bar
  3428.         if (gProgressCollapseTimer) {
  3429.           window.clearTimeout(gProgressCollapseTimer);
  3430.           gProgressCollapseTimer = null;
  3431.         }
  3432.         else
  3433.           this.statusMeter.parentNode.collapsed = false;
  3434.  
  3435.         // XXX: This needs to be based on window activity...
  3436.         this.stopCommand.removeAttribute("disabled");
  3437.     }
  3438.     else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
  3439.       if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
  3440.         if (aWebProgress.DOMWindow == content) {
  3441.           if (aRequest)
  3442.             this.endDocumentLoad(aRequest, aStatus);
  3443.           var browser = gBrowser.mCurrentBrowser;
  3444.           if (!gBrowser.mTabbedMode && !browser.mIconURL)
  3445.             gBrowser.useDefaultIcon(gBrowser.mCurrentTab);
  3446. //@line 3857 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3447.           if (browser.mIconURL)
  3448.             BookmarksUtils.loadFavIcon(browser.currentURI.spec, browser.mIconURL);
  3449. //@line 3860 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3450.         }
  3451.       }
  3452.  
  3453.       // This (thanks to the filter) is a network stop or the last
  3454.       // request stop outside of loading the document, stop throbbers
  3455.       // and progress bars and such
  3456.       if (aRequest) {
  3457.         var msg = "";
  3458.           // Get the URI either from a channel or a pseudo-object
  3459.           if (aRequest instanceof nsIChannel || "URI" in aRequest) {
  3460.             var location = aRequest.URI;
  3461.  
  3462.             // For keyword URIs clear the user typed value since they will be changed into real URIs
  3463.             if (location.scheme == "keyword" && aWebProgress.DOMWindow == content)
  3464.               getBrowser().userTypedValue = null;
  3465.  
  3466.             if (location.spec != "about:blank") {
  3467.               const kErrorBindingAborted = 0x804B0002;
  3468.               const kErrorNetTimeout = 0x804B000E;
  3469.               switch (aStatus) {
  3470.                 case kErrorBindingAborted:
  3471.                   msg = gNavigatorBundle.getString("nv_stopped");
  3472.                   break;
  3473.                 case kErrorNetTimeout:
  3474.                   msg = gNavigatorBundle.getString("nv_timeout");
  3475.                   break;
  3476.               }
  3477.             }
  3478.           }
  3479.           // If msg is false then we did not have an error (channel may have
  3480.           // been null, in the case of a stray image load).
  3481.           if (!msg && (!location || location.spec != "about:blank")) {
  3482.             msg = gNavigatorBundle.getString("nv_done");
  3483.           }
  3484.           this.status = "";
  3485.           this.setDefaultStatus(msg);
  3486.  
  3487.           // Disable menu entries for images, enable otherwise
  3488.           if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
  3489.             this.isImage.removeAttribute('disabled');
  3490.           else
  3491.             this.isImage.setAttribute('disabled', 'true');
  3492.         }
  3493.  
  3494.         // Turn the progress meter and throbber off.
  3495.         gProgressCollapseTimer = window.setTimeout(
  3496.           function() {
  3497.             gProgressMeterPanel.collapsed = true;
  3498.             gProgressCollapseTimer = null;
  3499.           }, 100);
  3500.  
  3501.         if (this.throbberElement)
  3502.           this.throbberElement.removeAttribute("busy");
  3503.  
  3504.         this.stopCommand.setAttribute("disabled", "true");
  3505.     }
  3506.   },
  3507.  
  3508.   onLocationChange : function(aWebProgress, aRequest, aLocation)
  3509.   {
  3510.     // This code here does not compare uris exactly when determining
  3511.     // whether or not the message should be hidden since the message
  3512.     // may be prematurely hidden when an install is invoked by a click
  3513.     // on a link that looks like this:
  3514.     //
  3515.     // <a href="#" onclick="return install();">Install Foo</a>
  3516.     //
  3517.     // - which fires a onLocationChange message to uri + '#'...
  3518.     var selectedBrowser = getBrowser().selectedBrowser;
  3519.     if (selectedBrowser.lastURI) {
  3520.       var oldSpec = selectedBrowser.lastURI.spec;
  3521.       var oldIndexOfHash = oldSpec.indexOf("#");
  3522.       if (oldIndexOfHash != -1)
  3523.         oldSpec = oldSpec.substr(0, oldIndexOfHash);
  3524.       var newSpec = aLocation.spec;
  3525.       var newIndexOfHash = newSpec.indexOf("#");
  3526.       if (newIndexOfHash != -1)
  3527.         newSpec = newSpec.substr(0, newSpec.indexOf("#"));
  3528.       if (newSpec != oldSpec) {
  3529.         // Per Bug #9306, don't remove account activation notifications
  3530.         // for piczo.com
  3531.         var host = null;
  3532.         try {
  3533.           host = selectedBrowser.lastURI.host;
  3534.         } catch (ex) {
  3535.           // may fail for non-HTTP URLs, but we don't care
  3536.         }
  3537.         if (host && (host.indexOf("piczo.com") != -1)) {
  3538.           // The Piczo case
  3539.           gBrowser.getNotificationBox(selectedBrowser)
  3540.                   .removeAllNotificationsExcept("accounts.account-setup-info-");
  3541.         } else {
  3542.           // The general case
  3543.           gBrowser.getNotificationBox(selectedBrowser).removeAllNotifications(true);
  3544.         }
  3545.       }
  3546.     }
  3547.     selectedBrowser.lastURI = aLocation;
  3548.  
  3549.     // Disable menu entries for images, enable otherwise
  3550.     if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
  3551.       this.isImage.removeAttribute('disabled');
  3552.     else
  3553.       this.isImage.setAttribute('disabled', 'true');
  3554.  
  3555.     this.setOverLink("", null);
  3556.  
  3557.     // We should probably not do this if the value has changed since the user
  3558.     // searched
  3559.     // Update urlbar only if a new page was loaded on the primary content area
  3560.     // Do not update urlbar if there was a subframe navigation
  3561.  
  3562.     var browser = getBrowser().selectedBrowser;
  3563.     var findField = document.getElementById("find-field");
  3564.     if (aWebProgress.DOMWindow == content) {
  3565.  
  3566.       var location = aLocation.spec;
  3567.  
  3568.       if ((location == "about:blank" && !content.opener) ||
  3569.            location == "") {                        //second condition is for new tabs, otherwise
  3570.         location = "";                              //reload function is enabled until tab is refreshed
  3571.         this.reloadCommand.setAttribute("disabled", "true");
  3572.         this.reloadSkipCacheCommand.setAttribute("disabled", "true");
  3573.       } else {
  3574.         this.reloadCommand.removeAttribute("disabled");
  3575.         this.reloadSkipCacheCommand.removeAttribute("disabled");
  3576.       }
  3577.  
  3578.       // The document loaded correctly, clear the value if we should
  3579.       if (browser.userTypedClear > 0 && aRequest)
  3580.         browser.userTypedValue = null;
  3581.  
  3582.       if (!gBrowser.mTabbedMode && aWebProgress.isLoadingDocument)
  3583.         gBrowser.setIcon(gBrowser.mCurrentTab, null);
  3584.  
  3585.       if (findField)
  3586.         setTimeout(function() { findField.value = browser.findString; }, 0, findField, browser);
  3587.  
  3588.       //XXXBlake don't we have to reinit this.urlBar, etc.
  3589.       //         when the toolbar changes?
  3590.       if (gURLBar) {
  3591.         var userTypedValue = browser.userTypedValue;
  3592.         if (!userTypedValue) {
  3593.           // If the url has "wyciwyg://" as the protocol, strip it off.
  3594.           // Nobody wants to see it on the urlbar for dynamically generated
  3595.           // pages.
  3596.           if (!gURIFixup)
  3597.             gURIFixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  3598.                                   .getService(Components.interfaces.nsIURIFixup);
  3599.           if (location && gURIFixup)
  3600.             try {
  3601.               var locationURI = gURIFixup.createExposableURI(aLocation);
  3602.               location = locationURI.spec;
  3603.             } catch (exception) {}
  3604.  
  3605.           if (getBrowser().forceSyncURLBarUpdate) {
  3606.             gURLBar.value = ""; // hack for bug 249322
  3607.             gURLBar.value = location;
  3608.             SetPageProxyState("valid");
  3609.           } else {
  3610.             setTimeout(function(loc) {
  3611.                          gURLBar.value = ""; // hack for bug 249322
  3612.                          gURLBar.value = loc;
  3613.                          SetPageProxyState("valid");
  3614.                        }, 0, location);
  3615.           }
  3616.  
  3617.           // Setting the urlBar value in some cases causes userTypedValue to
  3618.           // become set because of oninput, so reset it to its old value.
  3619.           browser.userTypedValue = userTypedValue;
  3620.         } else {
  3621.           gURLBar.value = userTypedValue;
  3622.           SetPageProxyState("invalid");
  3623.         }
  3624.       }
  3625.     }
  3626.     UpdateBackForwardButtons();
  3627.     if (findField && gFindBar.mFindMode != FIND_NORMAL) {
  3628.       // Close the Find toolbar if we're in old-style TAF mode
  3629.       gFindBar.closeFindBar();
  3630.     }
  3631.  
  3632.     //fix bug 253793 - turn off highlight when page changes
  3633.     if (document.getElementById("highlight").checked)
  3634.       document.getElementById("highlight").removeAttribute("checked");
  3635.  
  3636.     var self = this;
  3637.     setTimeout(function() { self.asyncUpdateUI(); }, 0);
  3638.   },
  3639.   
  3640.   asyncUpdateUI : function () {
  3641.     FeedHandler.updateFeeds();
  3642.     BrowserSearch.updateSearchButton();
  3643. //@line 4059 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  3644.   },
  3645.  
  3646.   onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
  3647.   {
  3648.     this.status = aMessage;
  3649.     this.updateStatusField();
  3650.   },
  3651.  
  3652.   onSecurityChange : function(aWebProgress, aRequest, aState)
  3653.   {
  3654.     const wpl = Components.interfaces.nsIWebProgressListener;
  3655.     this.securityButton.removeAttribute("label");
  3656.  
  3657.     switch (aState) {
  3658.       case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH:
  3659.         this.securityButton.setAttribute("level", "high");
  3660.         if (this.urlBar)
  3661.           this.urlBar.setAttribute("level", "high");
  3662.         try {
  3663.           this.securityButton.setAttribute("label",
  3664.             gBrowser.contentWindow.location.host);
  3665.         } catch(exception) {}
  3666.         break;
  3667.       case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_LOW:
  3668.         this.securityButton.setAttribute("level", "low");
  3669.         if (this.urlBar)
  3670.           this.urlBar.setAttribute("level", "low");
  3671.         try {
  3672.           this.securityButton.setAttribute("label",
  3673.             gBrowser.contentWindow.location.host);
  3674.         } catch(exception) {}
  3675.         break;
  3676.       case wpl.STATE_IS_BROKEN:
  3677.         this.securityButton.setAttribute("level", "broken");
  3678.         if (this.urlBar)
  3679.           this.urlBar.setAttribute("level", "broken");
  3680.         break;
  3681.       case wpl.STATE_IS_INSECURE:
  3682.       default:
  3683.         this.securityButton.removeAttribute("level");
  3684.         if (this.urlBar)
  3685.           this.urlBar.removeAttribute("level");
  3686.         break;
  3687.     }
  3688.  
  3689.     var securityUI = gBrowser.securityUI;
  3690.     this.securityButton.setAttribute("tooltiptext", securityUI.tooltipText);
  3691.     var lockIcon = document.getElementById("lock-icon");
  3692.     if (lockIcon)
  3693.       lockIcon.setAttribute("tooltiptext", securityUI.tooltipText);
  3694.   },
  3695.  
  3696.   // simulate all change notifications after switching tabs
  3697.   onUpdateCurrentBrowser : function(aStateFlags, aStatus, aMessage, aTotalProgress)
  3698.   {
  3699.     var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  3700.     var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
  3701.     // use a pseudo-object instead of a (potentially non-existing) channel for getting
  3702.     // a correct error message - and make sure that the UI is always either in
  3703.     // loading (STATE_START) or done (STATE_STOP) mode
  3704.     this.onStateChange(
  3705.       gBrowser.webProgress,
  3706.       { URI: gBrowser.currentURI },
  3707.       loadingDone ? nsIWebProgressListener.STATE_STOP : nsIWebProgressListener.STATE_START,
  3708.       aStatus
  3709.     );
  3710.     // status message and progress value are undefined if we're done with loading
  3711.     if (loadingDone)
  3712.       return;
  3713.     this.onStatusChange(gBrowser.webProgress, null, 0, aMessage);
  3714.     this.onProgressChange(gBrowser.webProgress, 0, 0, aTotalProgress, 1);
  3715.   },
  3716.  
  3717.   startDocumentLoad : function(aRequest)
  3718.   {
  3719.     this.docLoadEvent = gProfiler.profileEventStart("docload");
  3720.  
  3721.     // It's okay to clear what the user typed when we start
  3722.     // loading a document. If the user types, this counter gets
  3723.     // set to zero, if the document load ends without an
  3724.     // onLocationChange, this counter gets decremented
  3725.     // (so we keep it while switching tabs after failed loads)
  3726.     getBrowser().userTypedClear++;
  3727.  
  3728.     // clear out feed data
  3729.     gBrowser.mCurrentBrowser.feeds = null;
  3730.  
  3731.     // clear out search-engine data
  3732.     gBrowser.mCurrentBrowser.engines = null;
  3733.     gBrowser.mCurrentBrowser.hiddenEngines = null;
  3734.  
  3735.     const nsIChannel = Components.interfaces.nsIChannel;
  3736.     var urlStr = aRequest.QueryInterface(nsIChannel).URI.spec;
  3737.     var observerService = Components.classes["@mozilla.org/observer-service;1"]
  3738.                                     .getService(Components.interfaces.nsIObserverService);
  3739.     try {
  3740.       observerService.notifyObservers(content, "StartDocumentLoad", urlStr);
  3741.     } catch (e) {
  3742.     }
  3743.   },
  3744.  
  3745.   endDocumentLoad : function(aRequest, aStatus)
  3746.   {
  3747.     // The document is done loading, we no longer want the
  3748.     // value cleared.
  3749.     if (getBrowser().userTypedClear > 0)
  3750.       getBrowser().userTypedClear--;
  3751.  
  3752.     const nsIChannel = Components.interfaces.nsIChannel;
  3753.     var urlStr = aRequest.QueryInterface(nsIChannel).originalURI.spec;
  3754.  
  3755.     var observerService = Components.classes["@mozilla.org/observer-service;1"]
  3756.                                     .getService(Components.interfaces.nsIObserverService);
  3757.  
  3758.     var notification = Components.isSuccessCode(aStatus) ? "EndDocumentLoad" : "FailDocumentLoad";
  3759.     try {
  3760.       observerService.notifyObservers(content, notification, urlStr);
  3761.       dump ("Browser.js - Sent " +notification+ " Event\n");
  3762.     } catch (e) {
  3763.     }
  3764.     setTimeout(function() { if (document.getElementById("highlight").checked) toggleHighlight(true); }, 0);
  3765.     gProfiler.profileEventEnd(this.docLoadEvent, urlStr);
  3766.   }
  3767. }
  3768.  
  3769. function nsBrowserAccess()
  3770. {
  3771. }
  3772.  
  3773. nsBrowserAccess.prototype =
  3774. {
  3775.   QueryInterface : function(aIID)
  3776.   {
  3777.     if (aIID.equals(nsCI.nsIBrowserDOMWindow) ||
  3778.         aIID.equals(nsCI.nsISupports))
  3779.       return this;
  3780.     throw Components.results.NS_NOINTERFACE;
  3781.   },
  3782.  
  3783.   openURI : function(aURI, aOpener, aWhere, aContext)
  3784.   {
  3785.     var newWindow = null;
  3786.     var referrer = null;
  3787.     var isExternal = (aContext == nsCI.nsIBrowserDOMWindow.OPEN_EXTERNAL);
  3788.  
  3789.     if (isExternal && aURI && aURI.schemeIs("chrome")) {
  3790.       dump("use -chrome command-line option to load external chrome urls\n");
  3791.       return null;
  3792.     }
  3793.  
  3794.     var loadflags = isExternal ?
  3795.                        nsCI.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
  3796.                        nsCI.nsIWebNavigation.LOAD_FLAGS_NONE;
  3797.     var location;
  3798.     if (aWhere == nsCI.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW) {
  3799.       switch (aContext) {
  3800.         case nsCI.nsIBrowserDOMWindow.OPEN_EXTERNAL :
  3801.           aWhere = gPrefService.getIntPref("browser.link.open_external");
  3802.           break;
  3803.         default : // OPEN_NEW or an illegal value
  3804.           aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
  3805.       }
  3806.     }
  3807.     var url = aURI ? aURI.spec : "about:blank";
  3808.     switch(aWhere) {
  3809.       case nsCI.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
  3810.         newWindow = openDialog(getBrowserURL(), "_blank", "all,dialog=no", url);
  3811.         break;
  3812.       case nsCI.nsIBrowserDOMWindow.OPEN_NEWTAB :
  3813.         var loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
  3814.         var newTab = gBrowser.loadOneTab("about:blank", null, null, null, loadInBackground, false);
  3815.         newWindow = gBrowser.getBrowserForTab(newTab).docShell
  3816.                             .QueryInterface(nsCI.nsIInterfaceRequestor)
  3817.                             .getInterface(nsCI.nsIDOMWindow);
  3818.         try {
  3819.           if (aOpener) {
  3820.             location = aOpener.location;
  3821.             referrer =
  3822.                     Components.classes["@mozilla.org/network/io-service;1"]
  3823.                               .getService(Components.interfaces.nsIIOService)
  3824.                               .newURI(location, null, null);
  3825.           }
  3826.           newWindow.QueryInterface(nsCI.nsIInterfaceRequestor)
  3827.                    .getInterface(nsCI.nsIWebNavigation)
  3828.                    .loadURI(url, loadflags, referrer, null, null);
  3829.         } catch(e) {
  3830.         }
  3831.         break;
  3832.       default : // OPEN_CURRENTWINDOW or an illegal value
  3833.         try {
  3834.           if (aOpener) {
  3835.             newWindow = aOpener.top;
  3836.             location = aOpener.location;
  3837.             referrer =
  3838.                     Components.classes["@mozilla.org/network/io-service;1"]
  3839.                               .getService(Components.interfaces.nsIIOService)
  3840.                               .newURI(location, null, null);
  3841.  
  3842.             newWindow.QueryInterface(nsCI.nsIInterfaceRequestor)
  3843.                      .getInterface(nsIWebNavigation)
  3844.                      .loadURI(url, loadflags, referrer, null, null);
  3845.           } else {
  3846.             newWindow = gBrowser.selectedBrowser.docShell
  3847.                                 .QueryInterface(nsCI.nsIInterfaceRequestor)
  3848.                                 .getInterface(nsCI.nsIDOMWindow);
  3849.             getWebNavigation().loadURI(url, loadflags, null, null, null);
  3850.           }
  3851.           if(!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground"))
  3852.             content.focus();
  3853.         } catch(e) {
  3854.         }
  3855.     }
  3856.     return newWindow;
  3857.   },
  3858.  
  3859.   isTabContentWindow : function(aWindow)
  3860.   {
  3861.     var browsers = gBrowser.browsers;
  3862.     for (var ctr = 0; ctr < browsers.length; ctr++)
  3863.       if (browsers.item(ctr).contentWindow == aWindow)
  3864.         return true;
  3865.     return false;
  3866.   }
  3867. }
  3868.  
  3869. function onViewToolbarsPopupShowing(aEvent)
  3870. {
  3871.   var popup = aEvent.target;
  3872.   var i;
  3873.  
  3874.   // Empty the menu
  3875.   for (i = popup.childNodes.length-1; i >= 0; --i) {
  3876.     var deadItem = popup.childNodes[i];
  3877.     if (deadItem.hasAttribute("toolbarindex"))
  3878.       popup.removeChild(deadItem);
  3879.   }
  3880.  
  3881.   var firstMenuItem = popup.firstChild;
  3882.  
  3883.   var toolbox = document.getElementById("navigator-toolbox");
  3884.   for (i = 0; i < toolbox.childNodes.length; ++i) {
  3885.     var toolbar = toolbox.childNodes[i];
  3886.     var toolbarName = toolbar.getAttribute("toolbarname");
  3887.     var type = toolbar.getAttribute("type");
  3888.     if (toolbarName && type != "menubar") {
  3889.       var menuItem = document.createElement("menuitem");
  3890.       menuItem.setAttribute("toolbarindex", i);
  3891.       menuItem.setAttribute("type", "checkbox");
  3892.       menuItem.setAttribute("label", toolbarName);
  3893.       menuItem.setAttribute("accesskey", toolbar.getAttribute("accesskey"));
  3894.       menuItem.setAttribute("checked", toolbar.getAttribute("collapsed") != "true");
  3895.       popup.insertBefore(menuItem, firstMenuItem);
  3896.  
  3897.       menuItem.addEventListener("command", onViewToolbarCommand, false);
  3898.     }
  3899.     toolbar = toolbar.nextSibling;
  3900.   }
  3901. }
  3902.  
  3903. function onViewToolbarCommand(aEvent)
  3904. {
  3905.   var toolbox = document.getElementById("navigator-toolbox");
  3906.   var index = aEvent.originalTarget.getAttribute("toolbarindex");
  3907.   var toolbar = toolbox.childNodes[index];
  3908.  
  3909.   toolbar.collapsed = aEvent.originalTarget.getAttribute("checked") != "true";
  3910.   document.persist(toolbar.id, "collapsed");
  3911. }
  3912.  
  3913. function displaySecurityInfo()
  3914. {
  3915.   BrowserPageInfo(null, "securityTab");
  3916. }
  3917.  
  3918. // |forceOpen| is a bool that indicates that the sidebar should be forced open.  In other words
  3919. // the toggle won't be allowed to close the sidebar.
  3920. function toggleSidebar(aCommandID, forceOpen) {
  3921.  
  3922.   var sidebarBox = document.getElementById("sidebar-box");
  3923.   if (!aCommandID)
  3924.     aCommandID = sidebarBox.getAttribute("sidebarcommand");
  3925.  
  3926.   var elt = document.getElementById(aCommandID);
  3927.   var sidebar = document.getElementById("sidebar");
  3928.   var sidebarTitle = document.getElementById("sidebar-title");
  3929.   var sidebarSplitter = document.getElementById("sidebar-splitter");
  3930.  
  3931.   if (!forceOpen && elt.getAttribute("checked") == "true") {
  3932.     elt.removeAttribute("checked");
  3933.     sidebarBox.setAttribute("sidebarcommand", "");
  3934.     sidebarTitle.setAttribute("value", "");
  3935.     sidebarBox.hidden = true;
  3936.     sidebarSplitter.hidden = true;
  3937.     if (aCommandID != "flock_NewsSidebarBroadcaster")
  3938.       content.focus();
  3939.     return;
  3940.   }
  3941.  
  3942.   var elts = document.getElementsByAttribute("group", "sidebar");
  3943.   for (var i = 0; i < elts.length; ++i)
  3944.     elts[i].removeAttribute("checked");
  3945.  
  3946.   elt.setAttribute("checked", "true");;
  3947.  
  3948.   if (sidebarBox.hidden) {
  3949.     sidebarBox.hidden = false;
  3950.     sidebarSplitter.hidden = false;
  3951.   }
  3952.  
  3953.   var url = elt.getAttribute("sidebarurl");
  3954.   var title = elt.getAttribute("sidebartitle");
  3955.   if (!title)
  3956.     title = elt.getAttribute("label");
  3957.   sidebar.setAttribute("src", url);
  3958.   sidebarBox.setAttribute("src", url);
  3959.   sidebarBox.setAttribute("sidebarcommand", elt.id);
  3960.   sidebarTitle.setAttribute("value", title);
  3961.   if (aCommandID != "viewWebPanelsSidebar") { // no searchbox there
  3962.     // if the sidebar we want is already constructed, focus the searchbox
  3963.     if ((aCommandID == "viewBookmarksSidebar" && sidebar.contentDocument.getElementById("bookmarksPanel"))
  3964.     || (aCommandID == "viewHistorySidebar" && sidebar.contentDocument.getElementById("history-panel")))
  3965.       sidebar.contentDocument.getElementById("search-box").focus();
  3966.     // otherwiese, attach an onload handler
  3967.     else
  3968.       sidebar.addEventListener("load", asyncFocusSearchBox, true);
  3969.   }
  3970. }
  3971.  
  3972. function asyncFocusSearchBox(event)
  3973. {
  3974.   var sidebar = document.getElementById("sidebar");
  3975.   var searchBox = sidebar.contentDocument.getElementById("search-box");
  3976.   if (searchBox)
  3977.     searchBox.focus();
  3978.   sidebar.removeEventListener("load", asyncFocusSearchBox, true);
  3979.  }
  3980.  
  3981. var gHomeButton = {
  3982.   prefDomain: "browser.startup.homepage",
  3983.   observe: function (aSubject, aTopic, aPrefName)
  3984.   {
  3985.     if (aTopic != "nsPref:changed" || aPrefName != this.prefDomain)
  3986.       return;
  3987.  
  3988.     this.updateTooltip();
  3989.   },
  3990.  
  3991.   updateTooltip: function ()
  3992.   {
  3993.     var homeButton = document.getElementById("home-button");
  3994.     if (homeButton) {
  3995.       var homePage = this.getHomePage();
  3996.       homePage = homePage.replace(/\|/g,', ');
  3997.       homeButton.setAttribute("tooltiptext", homePage);
  3998.     }
  3999.   },
  4000.  
  4001.   getHomePage: function ()
  4002.   {
  4003.     var url;
  4004.     try {
  4005.       url = gPrefService.getComplexValue(this.prefDomain,
  4006.                                 Components.interfaces.nsIPrefLocalizedString).data;
  4007.     } catch (e) {
  4008.     }
  4009.  
  4010.     // use this if we can't find the pref
  4011.     if (!url) {
  4012.       var SBS = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
  4013.       var configBundle = SBS.createBundle("resource:/browserconfig.properties");
  4014.       url = configBundle.GetStringFromName(this.prefDomain);
  4015.     }
  4016.  
  4017.     return url;
  4018.   }
  4019. };
  4020.  
  4021. function nsContextMenu( xulMenu ) {
  4022.     this.target            = null;
  4023.     this.menu              = null;
  4024.     this.onTextInput       = false;
  4025.     this.onKeywordField    = false;
  4026.     this.onImage           = false;
  4027.     this.onLoadedImage     = false;
  4028.     this.onLink            = false;
  4029.     this.onMailtoLink      = false;
  4030.     this.onSaveableLink    = false;
  4031.     this.onMetaDataItem    = false;
  4032.     this.onMathML          = false;
  4033.     this.link              = false;
  4034.     this.linkURL           = "";
  4035.     this.linkURI           = null;
  4036.     this.linkProtocol      = null;
  4037.     this.inFrame           = false;
  4038.     this.hasBGImage        = false;
  4039.     this.isTextSelected    = false;
  4040.     this.isContentSelected = false;
  4041.     this.inDirList         = false;
  4042.     this.shouldDisplay     = true;
  4043.     this.isDesignMode      = false;
  4044.     this.possibleSpellChecking = false;
  4045.  
  4046.     // Initialize new menu.
  4047.     this.initMenu( xulMenu );
  4048. }
  4049.  
  4050. // Prototype for nsContextMenu "class."
  4051. nsContextMenu.prototype = {
  4052.     // onDestroy is a no-op at this point.
  4053.     onDestroy : function () {
  4054.     },
  4055.     // Initialize context menu.
  4056.     initMenu : function ( popup ) {
  4057.         // Save menu.
  4058.         this.menu = popup;
  4059.  
  4060.         // Get contextual info.
  4061.         this.setTarget( document.popupNode, document.popupRangeParent,
  4062.                         document.popupRangeOffset );
  4063.  
  4064.         this.isTextSelected = this.isTextSelection();
  4065.         this.isContentSelected = this.isContentSelection();
  4066.  
  4067.         // Initialize (disable/remove) menu items.
  4068.         this.initItems();
  4069.     },
  4070.     initItems : function () {
  4071.         this.initOpenItems();
  4072.         this.initNavigationItems();
  4073.         this.initViewItems();
  4074.         this.initMiscItems();
  4075.         this.initSpellingItems();
  4076.         this.initSaveItems();
  4077.         this.initClipboardItems();
  4078.         this.initMetadataItems();
  4079.     },
  4080.     initOpenItems : function () {
  4081.         this.showItem( "context-openlink", this.onSaveableLink || ( this.inDirList && this.onLink ) );
  4082.         this.showItem( "context-openlinkintab", this.onSaveableLink || ( this.inDirList && this.onLink ) );
  4083.  
  4084.         this.showItem( "context-sep-open", this.onSaveableLink || ( this.inDirList && this.onLink ) );
  4085.     },
  4086.     initNavigationItems : function () {
  4087.         // Back determined by canGoBack broadcaster.
  4088.         this.setItemAttrFromNode( "context-back", "disabled", "canGoBack" );
  4089.  
  4090.         // Forward determined by canGoForward broadcaster.
  4091.         this.setItemAttrFromNode( "context-forward", "disabled", "canGoForward" );
  4092.  
  4093.         this.showItem( "context-back", !( this.isContentSelected || this.onLink || this.onImage || this.onTextInput ) );
  4094.         this.showItem( "context-forward", !( this.isContentSelected || this.onLink || this.onImage || this.onTextInput ) );
  4095.  
  4096.         this.showItem( "context-reload", !( this.isContentSelected || this.onLink || this.onImage || this.onTextInput ) );
  4097.  
  4098.         this.showItem( "context-stop", !( this.isContentSelected || this.onLink || this.onImage || this.onTextInput ) );
  4099.         this.showItem( "context-sep-stop", !( this.isContentSelected || this.onLink || this.onTextInput || this.onImage ) );
  4100.  
  4101.         // XXX: Stop is determined in navigator.js; the canStop broadcaster is broken
  4102.         //this.setItemAttrFromNode( "context-stop", "disabled", "canStop" );
  4103.     },
  4104.     initSaveItems : function () {
  4105.         this.showItem( "context-savepage", !( this.inDirList || this.isContentSelected || this.onTextInput || this.onLink || this.onImage ));
  4106.         this.showItem( "context-sendpage", !( this.inDirList || this.isContentSelected || this.onTextInput || this.onLink || this.onImage ));
  4107.  
  4108.         // Save+Send link depends on whether we're in a link.
  4109.         this.showItem( "context-savelink", this.onSaveableLink );
  4110.         this.showItem( "context-sendlink", this.onSaveableLink );
  4111.  
  4112.         // Save+Send image depends on whether we're on an image.
  4113.         this.showItem( "context-saveimage", this.onLoadedImage );
  4114.         this.showItem( "context-sendimage", this.onImage );
  4115.         
  4116.         // Flock modification: upload image
  4117.         this.showItem( "context-uploadimage", this.onImage );
  4118.     },
  4119.     initViewItems : function () {
  4120.         // View source is always OK, unless in directory listing.
  4121.         this.showItem( "context-viewpartialsource-selection", this.isContentSelected );
  4122.         this.showItem( "context-viewpartialsource-mathml", this.onMathML && !this.isContentSelected );
  4123.         this.showItem( "context-viewsource", !( this.inDirList || this.onImage || this.isContentSelected || this.onLink || this.onTextInput ) );
  4124.         this.showItem( "context-viewinfo", !( this.inDirList || this.onImage || this.isContentSelected || this.onLink || this.onTextInput ) );
  4125.  
  4126.         this.showItem( "context-sep-properties", !( this.inDirList || this.isContentSelected || this.onTextInput ) );
  4127.         // Set as Desktop background depends on whether an image was clicked on,
  4128.         // and only works if we have a shell service.
  4129.         var haveSetDesktopBackground = false;
  4130. //@line 4546 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4131.         // Only enable Set as Desktop Background if we can get the shell service.
  4132.         var shell = getShellService();
  4133.         if (shell)
  4134.           haveSetDesktopBackground = true;
  4135. //@line 4551 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4136.         this.showItem( "context-setDesktopBackground", haveSetDesktopBackground && this.onLoadedImage );
  4137.  
  4138.         if ( haveSetDesktopBackground && this.onLoadedImage )
  4139.             this.setItemAttr( "context-setDesktopBackground", "disabled", this.disableSetDesktopBackground());
  4140.  
  4141.         // View Image depends on whether an image was clicked on.
  4142.         this.showItem( "context-viewimage", this.onImage  && ( !this.onStandaloneImage || this.inFrame ) );
  4143.  
  4144.         // View background image depends on whether there is one.
  4145.         this.showItem( "context-viewbgimage", !( this.inDirList || this.onImage || this.isContentSelected || this.onLink || this.onTextInput ) );
  4146.         this.showItem( "context-sep-viewbgimage", !( this.inDirList || this.onImage || this.isContentSelected || this.onLink || this.onTextInput ) );
  4147.         this.setItemAttr( "context-viewbgimage", "disabled", this.hasBGImage ? null : "true");
  4148.     },
  4149.     initMiscItems : function () {
  4150.         // Use "Bookmark This Link" if on a link.
  4151.         this.showItem( "context-bookmarkpage", !( this.isContentSelected || this.onTextInput || this.onLink || this.onImage ) );
  4152.         this.showItem( "context-bookmarklink", this.onLink && !this.onMailtoLink );
  4153.         this.showItem( "context-searchselect", this.isTextSelected );
  4154.         this.showItem( "context-keywordfield", this.onTextInput && this.onKeywordField );
  4155.         this.showItem( "frame", this.inFrame );
  4156.         this.showItem( "frame-sep", this.inFrame );
  4157.  
  4158.         // BiDi UI
  4159.         this.showItem( "context-sep-bidi", gBidiUI);
  4160.         this.showItem( "context-bidi-text-direction-toggle", this.onTextInput && gBidiUI);
  4161.         this.showItem( "context-bidi-page-direction-toggle", !this.onTextInput && gBidiUI);
  4162.  
  4163.         if (this.onImage) {
  4164.           var blockImage = document.getElementById("context-blockimage");
  4165.  
  4166.           var uri = this.target.QueryInterface(Components.interfaces.nsIImageLoadingContent).currentURI;
  4167.  
  4168.           var hostLabel;
  4169.           // this throws if the image URI doesn't have a host (eg, data: image URIs)
  4170.           // see bug 293758 for details
  4171.           try {
  4172.             hostLabel = uri.host;
  4173.           } catch (ex) { }
  4174.  
  4175.           if (hostLabel) {
  4176.             var shortenedUriHost = hostLabel.replace(/^www\./i,"");
  4177.             if (shortenedUriHost.length > 15)
  4178.               shortenedUriHost = shortenedUriHost.substr(0,15) + "...";
  4179.             blockImage.label = gNavigatorBundle.getFormattedString("blockImages", [shortenedUriHost]);
  4180.  
  4181.             if (this.isImageBlocked())
  4182.               blockImage.setAttribute("checked", "true");
  4183.             else
  4184.               blockImage.removeAttribute("checked");
  4185.           }
  4186.         }
  4187.  
  4188.         // Only show the block image item if the image can be blocked
  4189.         this.showItem( "context-blockimage", this.onImage && hostLabel);
  4190.     },
  4191.     initSpellingItems : function () {
  4192.         var canSpell = InlineSpellCheckerUI.canSpellCheck;
  4193.         var onMisspelling = InlineSpellCheckerUI.overMisspelling;
  4194.         this.showItem("spell-check-enabled", canSpell);
  4195.         this.showItem("spell-separator", canSpell || this.possibleSpellChecking);
  4196.         if (canSpell)
  4197.             document.getElementById("spell-check-enabled").setAttribute("checked",
  4198.                                                                         InlineSpellCheckerUI.enabled);
  4199.         this.showItem("spell-add-to-dictionary", onMisspelling);
  4200.  
  4201.         // suggestion list
  4202.         this.showItem("spell-suggestions-separator", onMisspelling);
  4203.         if (onMisspelling) {
  4204.             var menu = document.getElementById("contentAreaContextMenu");
  4205.             var suggestionsSeparator = document.getElementById("spell-add-to-dictionary");
  4206.             var numsug = InlineSpellCheckerUI.addSuggestionsToMenu(menu, suggestionsSeparator, 5);
  4207.             this.showItem("spell-no-suggestions", numsug == 0);
  4208.         } else {
  4209.             this.showItem("spell-no-suggestions", false);
  4210.         }
  4211.  
  4212.         // dictionary list
  4213.         this.showItem("spell-dictionaries", InlineSpellCheckerUI.enabled);
  4214.         if (canSpell) {
  4215.             var dictMenu = document.getElementById("spell-dictionaries-menu");
  4216.             var dictSep = document.getElementById("spell-language-separator");
  4217.             InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep);
  4218.             this.showItem("spell-add-dictionaries-main", false);
  4219.         } else if (this.possibleSpellChecking) {
  4220.             // when there is no spellchecker but we might be able to spellcheck
  4221.             // add the add to dictionaries item. This will ensure that people
  4222.             // with no dictionaries will be able to download them
  4223.             this.showItem("spell-add-dictionaries-main", true);
  4224.         } else {
  4225.             this.showItem("spell-add-dictionaries-main", false);
  4226.         }
  4227.     },
  4228.     initClipboardItems : function () {
  4229.  
  4230.         // Copy depends on whether there is selected text.
  4231.         // Enabling this context menu item is now done through the global
  4232.         // command updating system
  4233.         // this.setItemAttr( "context-copy", "disabled", !this.isTextSelected() );
  4234.  
  4235.         goUpdateGlobalEditMenuItems();
  4236.  
  4237.         this.showItem( "context-undo", this.onTextInput );
  4238.         this.showItem( "context-sep-undo", this.onTextInput );
  4239.         this.showItem( "context-cut", this.onTextInput );
  4240.         this.showItem( "context-copy", this.isContentSelected || this.onTextInput );
  4241.         this.showItem( "context-paste", this.onTextInput );
  4242.         this.showItem( "context-delete", this.onTextInput );
  4243.         this.showItem( "context-sep-paste", this.onTextInput );
  4244.         this.showItem( "context-selectall", !( this.onLink || this.onImage ) || this.isDesignMode );
  4245.         this.showItem( "context-sep-selectall", this.isContentSelected );
  4246.  
  4247.         // XXX dr
  4248.         // ------
  4249.         // nsDocumentViewer.cpp has code to determine whether we're
  4250.         // on a link or an image. we really ought to be using that...
  4251.  
  4252.         // Copy email link depends on whether we're on an email link.
  4253.         this.showItem( "context-copyemail", this.onMailtoLink );
  4254.  
  4255.         // Copy link location depends on whether we're on a link.
  4256.         this.showItem( "context-copylink", this.onLink );
  4257.         this.showItem( "context-sep-copylink", this.onLink && this.onImage);
  4258.  
  4259. //@line 4675 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4260.         // Copy image contents depends on whether we're on an image.
  4261.         this.showItem( "context-copyimage-contents", this.onImage );
  4262. //@line 4678 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4263.         // Copy image location depends on whether we're on an image.
  4264.         this.showItem( "context-copyimage", this.onImage );
  4265.         this.showItem( "context-sep-copyimage", this.onImage );
  4266.     },
  4267.     initMetadataItems : function () {
  4268.         // Show if user clicked on something which has metadata.
  4269.         this.showItem( "context-metadata", this.onMetaDataItem );
  4270.     },
  4271.     // Set various context menu attributes based on the state of the world.
  4272.     setTarget : function ( node, rangeParent, rangeOffset ) {
  4273.         const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
  4274.         if ( node.namespaceURI == xulNS ) {
  4275.           this.shouldDisplay = false;
  4276.           return;
  4277.         }
  4278.  
  4279.         // Initialize contextual info.
  4280.         this.onImage           = false;
  4281.         this.onLoadedImage     = false;
  4282.         this.onStandaloneImage = false;
  4283.         this.onMetaDataItem    = false;
  4284.         this.onTextInput       = false;
  4285.         this.onKeywordField    = false;
  4286.         this.imageURL          = "";
  4287.         this.onLink            = false;
  4288.         this.linkURL           = "";
  4289.         this.linkURI           = null;
  4290.         this.linkProtocol      = "";
  4291.         this.onMathML          = false;
  4292.         this.inFrame           = false;
  4293.         this.hasBGImage        = false;
  4294.         this.bgImageURL        = "";
  4295.         this.possibleSpellChecking = false;
  4296.  
  4297.         // Clear any old spellchecking items from the menu, this used to
  4298.         // be in the menu hiding code but wasn't getting called in all
  4299.         // situations. Here, we can ensure it gets cleaned up any time the
  4300.         // menu is shown. Note: must be before uninit because that clears the
  4301.         // internal vars
  4302.         InlineSpellCheckerUI.clearSuggestionsFromMenu();
  4303.         InlineSpellCheckerUI.clearDictionaryListFromMenu();
  4304.  
  4305.         InlineSpellCheckerUI.uninit();
  4306.  
  4307.         // Remember the node that was clicked.
  4308.         this.target = node;
  4309.         
  4310.         // Remember the URL of the document containing the node
  4311.         // for referrer header and for security checks.
  4312.         this.docURL = node.ownerDocument.location.href;
  4313.  
  4314.         //BEGIN FLOCK
  4315.         // this is a fix to allow midas copy and paste work on websites 
  4316.         // and within the blog editor
  4317.         if (typeof node.ownerDocument.designMode != "undefined"
  4318.         && node.ownerDocument.designMode.toLowerCase() == "on") {
  4319.             this.onTextInput = true;
  4320.         }
  4321.         //END FLOCK
  4322.  
  4323.         // First, do checks for nodes that never have children.
  4324.         if ( this.target.nodeType == Node.ELEMENT_NODE ) {
  4325.             // See if the user clicked on an image.
  4326.             if ( this.target instanceof Components.interfaces.nsIImageLoadingContent && this.target.currentURI  ) {
  4327.                 this.onImage = true;
  4328.                 this.onMetaDataItem = true;
  4329.                         
  4330.                 var request = this.target.getRequest( Components.interfaces.nsIImageLoadingContent.CURRENT_REQUEST );
  4331.                 if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
  4332.                     this.onLoadedImage = true;
  4333.                 this.imageURL = this.target.currentURI.spec;
  4334.  
  4335.                 if ( this.target.ownerDocument instanceof ImageDocument)
  4336.                    this.onStandaloneImage = true;
  4337.             } else if ( this.target instanceof HTMLInputElement ) {
  4338.                this.onTextInput = this.isTargetATextBox(this.target);
  4339.                // allow spellchecking UI on all writable text boxes except passwords
  4340.                if (this.onTextInput && ! this.target.readOnly && this.target.type != "password") {
  4341.                    this.possibleSpellChecking = true;
  4342.                    InlineSpellCheckerUI.init(this.target.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor);
  4343.                    InlineSpellCheckerUI.initFromEvent(rangeParent, rangeOffset);
  4344.                }
  4345.                this.onKeywordField = this.isTargetAKeywordField(this.target);
  4346.             } else if ( this.target instanceof HTMLTextAreaElement ) {
  4347.                  this.onTextInput = true;
  4348.                  if (! this.target.readOnly) {
  4349.                      this.possibleSpellChecking = true;
  4350.                      InlineSpellCheckerUI.init(this.target.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor);
  4351.                      InlineSpellCheckerUI.initFromEvent(rangeParent, rangeOffset);
  4352.                  }
  4353.             } else if ( this.target instanceof HTMLHtmlElement ) {
  4354.                // pages with multiple <body>s are lame. we'll teach them a lesson.
  4355.                var bodyElt = this.target.ownerDocument.getElementsByTagName("body")[0];
  4356.                if ( bodyElt ) {
  4357.                  var computedURL = this.getComputedURL( bodyElt, "background-image" );
  4358.                  if ( computedURL ) {
  4359.                    this.hasBGImage = true;
  4360.                    this.bgImageURL = makeURLAbsolute( bodyElt.baseURI,
  4361.                                                       computedURL );
  4362.                  }
  4363.                }
  4364.             } else if ( "HTTPIndex" in content &&
  4365.                         content.HTTPIndex instanceof Components.interfaces.nsIHTTPIndex ) {
  4366.                 this.inDirList = true;
  4367.                 // Bubble outward till we get to an element with URL attribute
  4368.                 // (which should be the href).
  4369.                 var root = this.target;
  4370.                 while ( root && !this.link ) {
  4371.                     if ( root.tagName == "tree" ) {
  4372.                         // Hit root of tree; must have clicked in empty space;
  4373.                         // thus, no link.
  4374.                         break;
  4375.                     }
  4376.                     if ( root.getAttribute( "URL" ) ) {
  4377.                         // Build pseudo link object so link-related functions work.
  4378.                         this.onLink = true;
  4379.                         this.link = { href : root.getAttribute("URL"),
  4380.                                       getAttribute: function (attr) {
  4381.                                           if (attr == "title") {
  4382.                                               return root.firstChild.firstChild.getAttribute("label");
  4383.                                           } else {
  4384.                                               return "";
  4385.                                           }
  4386.                                       }
  4387.                                     };
  4388.                         // If element is a directory, then you can't save it.
  4389.                         if ( root.getAttribute( "container" ) == "true" ) {
  4390.                             this.onSaveableLink = false;
  4391.                         } else {
  4392.                             this.onSaveableLink = true;
  4393.                         }
  4394.                     } else {
  4395.                         root = root.parentNode;
  4396.                     }
  4397.                 }
  4398.             }
  4399.         }
  4400.  
  4401.         // Second, bubble out, looking for items of interest that can have childen.
  4402.         // Always pick the innermost link, background image, etc.
  4403.         
  4404.         const XMLNS = "http://www.w3.org/XML/1998/namespace";
  4405.         var elem = this.target;
  4406.         while ( elem ) {
  4407.             if ( elem.nodeType == Node.ELEMENT_NODE ) {
  4408.             
  4409.                 // Link?
  4410.                 if ( !this.onLink &&
  4411.                      ( (elem instanceof HTMLAnchorElement && elem.href) ||
  4412.                         elem instanceof HTMLAreaElement ||
  4413.                         elem instanceof HTMLLinkElement ||
  4414.                         elem.getAttributeNS( "http://www.w3.org/1999/xlink", "type") == "simple" ) ) {
  4415.                     
  4416.                     // Target is a link or a descendant of a link.
  4417.                     this.onLink = true;
  4418.                     this.onMetaDataItem = true;
  4419.  
  4420.                     // xxxmpc: this is kind of a hack to work around a Gecko bug (see bug 266932)
  4421.                     // we're going to walk up the DOM looking for a parent link node,
  4422.                     // this shouldn't be necessary, but we're matching the existing behaviour for left click
  4423.                     var realLink = elem;
  4424.                     var parent = elem.parentNode;
  4425.                     while (parent) {
  4426.                       try {
  4427.                         if ( (parent instanceof HTMLAnchorElement && elem.href) ||
  4428.                              parent instanceof HTMLAreaElement ||
  4429.                              parent instanceof HTMLLinkElement ||
  4430.                              parent.getAttributeNS( "http://www.w3.org/1999/xlink", "type") == "simple")
  4431.                           realLink = parent;
  4432.                       } catch (e) {}
  4433.                       parent = parent.parentNode;
  4434.                     }
  4435.                     
  4436.                     // Remember corresponding element.
  4437.                     this.link = realLink;
  4438.                     this.linkURL = this.getLinkURL();
  4439.                     this.linkURI = this.getLinkURI();
  4440.                     this.linkProtocol = this.getLinkProtocol();
  4441.                     this.onMailtoLink = (this.linkProtocol == "mailto");
  4442.                     this.onSaveableLink = this.isLinkSaveable( this.link );
  4443.                 }
  4444.  
  4445.                 // Metadata item?
  4446.                 if ( !this.onMetaDataItem ) {
  4447.                     // We display metadata on anything which fits
  4448.                     // the below test, as well as for links and images
  4449.                     // (which set this.onMetaDataItem to true elsewhere)
  4450.                     if ( ( elem instanceof HTMLQuoteElement && elem.cite)    ||
  4451.                          ( elem instanceof HTMLTableElement && elem.summary) ||
  4452.                          ( elem instanceof HTMLModElement &&
  4453.                              ( elem.cite || elem.dateTime ) )                ||
  4454.                          ( elem instanceof HTMLElement &&
  4455.                              ( elem.title || elem.lang ) )                   ||
  4456.                          elem.getAttributeNS(XMLNS, "lang") ) {
  4457.                         this.onMetaDataItem = true;
  4458.                     }
  4459.                 }
  4460.  
  4461.                 // Background image?  Don't bother if we've already found a
  4462.                 // background image further down the hierarchy.  Otherwise,
  4463.                 // we look for the computed background-image style.
  4464.                 if ( !this.hasBGImage ) {
  4465.                     var bgImgUrl = this.getComputedURL( elem, "background-image" );
  4466.                     if ( bgImgUrl ) {
  4467.                         this.hasBGImage = true;
  4468.                         this.bgImageURL = makeURLAbsolute( elem.baseURI,
  4469.                                                            bgImgUrl );
  4470.                     }
  4471.                 }
  4472.             }
  4473.             elem = elem.parentNode;
  4474.         }
  4475.         
  4476.         // See if the user clicked on MathML
  4477.         const NS_MathML = "http://www.w3.org/1998/Math/MathML";
  4478.         if ((this.target.nodeType == Node.TEXT_NODE &&
  4479.              this.target.parentNode.namespaceURI == NS_MathML)
  4480.              || (this.target.namespaceURI == NS_MathML))
  4481.           this.onMathML = true;
  4482.  
  4483.         // See if the user clicked in a frame.
  4484.         if ( this.target.ownerDocument != window.content.document ) {
  4485.             this.inFrame = true;
  4486.         }
  4487.  
  4488.         // if the document is editable, show context menu like in text inputs
  4489.         var win = this.target.ownerDocument.defaultView;
  4490.         if (win) {
  4491.           var editingSession = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  4492.                                   .getInterface(Components.interfaces.nsIWebNavigation)
  4493.                                   .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
  4494.                                   .getInterface(Components.interfaces.nsIEditingSession);
  4495.           if (editingSession.windowIsEditable(win)) {
  4496.             this.onTextInput       = true;
  4497.             this.onKeywordField    = false;
  4498.             this.onImage           = false;
  4499.             this.onLoadedImage     = false;
  4500.             this.onMetaDataItem    = false;
  4501.             this.onMathML          = false;
  4502.             this.inFrame           = false;
  4503.             this.hasBGImage        = false;
  4504.             this.isDesignMode      = true;
  4505.             this.possibleSpellChecking = true;
  4506.             InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
  4507.             var canSpell = InlineSpellCheckerUI.canSpellCheck;
  4508.             InlineSpellCheckerUI.initFromEvent(rangeParent, rangeOffset);
  4509.             this.showItem("spell-check-enabled", canSpell);
  4510.             this.showItem("spell-separator", canSpell);
  4511.           }
  4512.         }
  4513.     },
  4514.     // Returns the computed style attribute for the given element.
  4515.     getComputedStyle: function( elem, prop ) {
  4516.          return elem.ownerDocument.defaultView.getComputedStyle( elem, '' ).getPropertyValue( prop );
  4517.     },
  4518.     // Returns a "url"-type computed style attribute value, with the url() stripped.
  4519.     getComputedURL: function( elem, prop ) {
  4520.          var url = elem.ownerDocument.defaultView.getComputedStyle( elem, '' ).getPropertyCSSValue( prop );
  4521.          return ( url.primitiveType == CSSPrimitiveValue.CSS_URI ) ? url.getStringValue() : null;
  4522.     },
  4523.     // Returns true if clicked-on link targets a resource that can be saved.
  4524.     isLinkSaveable : function ( link ) {
  4525.         // We don't do the Right Thing for news/snews yet, so turn them off
  4526.         // until we do.
  4527.         return this.linkProtocol && !(
  4528.                  this.linkProtocol == "mailto"     ||
  4529.                  this.linkProtocol == "javascript" ||
  4530.                  this.linkProtocol == "news"       ||
  4531.                  this.linkProtocol == "snews"      );
  4532.     },
  4533.  
  4534.     // Open linked-to URL in a new window.
  4535.     openLink : function () {
  4536.         openNewWindowWith(this.linkURL, this.docURL, null, false);
  4537.     },
  4538.     // Open linked-to URL in a new tab.
  4539.     openLinkInTab : function () {
  4540.         openNewTabWith(this.linkURL, this.docURL, null, null, false);
  4541.     },
  4542.     // Open frame in a new tab.
  4543.     openFrameInTab : function () {
  4544.         openNewTabWith(this.target.ownerDocument.location.href, null, null, null, false);
  4545.     },
  4546.     // Reload clicked-in frame.
  4547.     reloadFrame : function () {
  4548.         this.target.ownerDocument.location.reload();
  4549.     },
  4550.     // Open clicked-in frame in its own window.
  4551.     openFrame : function () {
  4552.         openNewWindowWith(this.target.ownerDocument.location.href, null, null, false);
  4553.     },
  4554.     // Open clicked-in frame in the same window.
  4555.     showOnlyThisFrame : function () {
  4556.       const nsIScriptSecMan = Components.interfaces.nsIScriptSecurityManager;
  4557.       var frameURL = this.target.ownerDocument.location.href;
  4558.  
  4559.       try {
  4560.         urlSecurityCheck(frameURL, gBrowser.currentURI.spec,
  4561.                          nsIScriptSecMan.DISALLOW_SCRIPT);
  4562.         window.loadURI(frameURL, null, null, false);
  4563.       } catch(e) {}
  4564.     },
  4565.     // View Partial Source
  4566.     viewPartialSource : function ( context ) {
  4567.         var focusedWindow = document.commandDispatcher.focusedWindow;
  4568.         if (focusedWindow == window)
  4569.           focusedWindow = content;
  4570.         var docCharset = null;
  4571.         if (focusedWindow)
  4572.           docCharset = "charset=" + focusedWindow.document.characterSet;
  4573.  
  4574.         // "View Selection Source" and others such as "View MathML Source"
  4575.         // are mutually exclusive, with the precedence given to the selection
  4576.         // when there is one
  4577.         var reference = null;
  4578.         if (context == "selection")
  4579.           reference = focusedWindow.getSelection();
  4580.         else if (context == "mathml")
  4581.           reference = this.target;
  4582.         else
  4583.           throw "not reached";
  4584.  
  4585.         var docUrl = null; // unused (and play nice for fragments generated via XSLT too)
  4586.         window.openDialog("chrome://global/content/viewPartialSource.xul",
  4587.                           "_blank", "scrollbars,resizable,chrome,dialog=no",
  4588.                           docUrl, docCharset, reference, context);
  4589.     },
  4590.     // Open new "view source" window with the frame's URL.
  4591.     viewFrameSource : function () {
  4592.         BrowserViewSourceOfDocument(this.target.ownerDocument);
  4593.     },
  4594.     viewInfo : function () {
  4595.       BrowserPageInfo();
  4596.     },
  4597.     viewFrameInfo : function () {
  4598.       BrowserPageInfo(this.target.ownerDocument);
  4599.     },
  4600.     // Change current window to the URL of the image.
  4601.     viewImage : function (e) {
  4602.         const nsIScriptSecMan = Components.interfaces.nsIScriptSecurityManager;
  4603.         urlSecurityCheck( this.imageURL, gBrowser.currentURI.spec,
  4604.                           nsIScriptSecMan.DISALLOW_SCRIPT );
  4605.         openUILink( this.imageURL, e );
  4606.     },
  4607.     // Change current window to the URL of the background image.
  4608.     viewBGImage : function (e) {
  4609.         const nsIScriptSecMan = Components.interfaces.nsIScriptSecurityManager;
  4610.         urlSecurityCheck( this.bgImageURL, gBrowser.currentURI.spec,
  4611.                           nsIScriptSecMan.DISALLOW_SCRIPT );
  4612.         openUILink( this.bgImageURL, e );
  4613.     },
  4614.     disableSetDesktopBackground: function() {
  4615.         // Disable the Set as Desktop Background menu item if we're still trying
  4616.         // to load the image or the load failed.
  4617.  
  4618.         const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent;
  4619.         if (!(this.target instanceof nsIImageLoadingContent))
  4620.             return true;
  4621.  
  4622.         if (("complete" in this.target) && !this.target.complete)
  4623.             return true;
  4624.  
  4625.         if (this.target.currentURI.schemeIs("javascript"))
  4626.             return true;
  4627.  
  4628.         var request = this.target.QueryInterface(nsIImageLoadingContent)
  4629.                                  .getRequest(nsIImageLoadingContent.CURRENT_REQUEST);
  4630.         if (!request)
  4631.             return true;
  4632.  
  4633.         return false;
  4634.     },
  4635.     setDesktopBackground: function() {
  4636.       // Paranoia: check disableSetDesktopBackground again, in case the
  4637.       // image changed since the context menu was initiated.
  4638.       if (this.disableSetDesktopBackground())
  4639.         return;
  4640.  
  4641.       urlSecurityCheck(this.target.currentURI.spec, this.docURL);
  4642.  
  4643.       // Confirm since it's annoying if you hit this accidentally.
  4644.       const kDesktopBackgroundURL = 
  4645.                     "chrome://browser/content/setDesktopBackground.xul";
  4646. //@line 5077 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4647.       // On non-Mac platforms, the Set Wallpaper dialog is modal.
  4648.       openDialog(kDesktopBackgroundURL, "",
  4649.                  "centerscreen,chrome,dialog,modal,dependent",
  4650.                  this.target);
  4651. //@line 5082 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4652.     },
  4653.     // Save URL of clicked-on frame.
  4654.     saveFrame : function () {
  4655.         saveDocument( this.target.ownerDocument );
  4656.     },
  4657.     // Save URL of clicked-on link.
  4658.     saveLink : function () {
  4659.         urlSecurityCheck(this.linkURL, this.docURL);
  4660.         saveURL( this.linkURL, this.linkText(), null, true, false,
  4661.                  makeURI(this.docURL, this.target.ownerDocument.characterSet) );
  4662.     },
  4663.     sendLink : function () {
  4664.         MailIntegration.sendMessage( this.linkURL, "" ); // we don't know the title of the link so pass in an empty string
  4665.     },
  4666.     // Save URL of clicked-on image.
  4667.     saveImage : function () {
  4668.         urlSecurityCheck(this.imageURL, this.docURL);
  4669.         saveImageURL( this.imageURL, null, "SaveImageTitle", false,
  4670.                       false, makeURI(this.docURL) );
  4671.     },
  4672.     sendImage : function () {
  4673.         MailIntegration.sendMessage(this.imageURL, "");
  4674.     },
  4675.     toggleImageBlocking : function (aBlock) {
  4676.       var nsIPermissionManager = Components.interfaces.nsIPermissionManager;
  4677.       var permissionmanager =
  4678.         Components.classes["@mozilla.org/permissionmanager;1"]
  4679.                   .getService(nsIPermissionManager);
  4680.  
  4681.       var uri = this.target.QueryInterface(Components.interfaces.nsIImageLoadingContent).currentURI;
  4682.  
  4683.       permissionmanager.add(uri, "image",
  4684.                             aBlock ? nsIPermissionManager.DENY_ACTION : nsIPermissionManager.ALLOW_ACTION);
  4685.  
  4686.       var savedmenu = this;
  4687.       function undoImageBlock() {
  4688.         savedmenu.toggleImageBlocking(!aBlock);
  4689.       }
  4690.  
  4691.       var brandBundle = document.getElementById("bundle_brand");
  4692.       var app = brandBundle.getString("brandShortName");
  4693.       var bundle_browser = document.getElementById("bundle_browser");
  4694.       var message;
  4695.       if (aBlock)
  4696.         message = bundle_browser.getFormattedString("imageBlockedWarning",
  4697.                                                     [app, uri.host]);
  4698.       else 
  4699.         message = bundle_browser.getFormattedString("imageAllowedWarning",
  4700.                                                     [app, uri.host]);
  4701.  
  4702.       var notificationBox = gBrowser.getNotificationBox();
  4703.       var notification = notificationBox.getNotificationWithValue("images-blocked");
  4704.  
  4705.       if (notification)
  4706.         notification.label = message;
  4707.       else {
  4708.         var buttons = [{
  4709.           label: bundle_browser.getString("undo"),
  4710.           accessKey: bundle_browser.getString("undo.accessKey"),
  4711.           callback: undoImageBlock
  4712.          }];
  4713.          const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
  4714.          notificationBox.appendNotification(message, "images-blocked",
  4715.                                             "chrome://browser/skin/Info.png",
  4716.                                              priority, buttons);
  4717.       }
  4718.  
  4719.       // Reload the page to show the effect instantly
  4720.       BrowserReload();
  4721.     },
  4722.     isImageBlocked : function() {
  4723.       var nsIPermissionManager = Components.interfaces.nsIPermissionManager;
  4724.       var permissionmanager =
  4725.         Components.classes["@mozilla.org/permissionmanager;1"]
  4726.           .getService(Components.interfaces.nsIPermissionManager);
  4727.  
  4728.       var uri = this.target.QueryInterface(Components.interfaces.nsIImageLoadingContent).currentURI;
  4729.  
  4730.       return permissionmanager.testPermission(uri, "image") == nsIPermissionManager.DENY_ACTION;
  4731.     },
  4732.     // Generate email address and put it on clipboard.
  4733.     copyEmail : function () {
  4734.         // Copy the comma-separated list of email addresses only.
  4735.         // There are other ways of embedding email addresses in a mailto:
  4736.         // link, but such complex parsing is beyond us.
  4737.         var url = this.linkURL;
  4738.  
  4739.         var qmark = url.indexOf( "?" );
  4740.         var addresses;
  4741.  
  4742.         if ( qmark > 7 ) {                   // 7 == length of "mailto:"
  4743.             addresses = url.substring( 7, qmark );
  4744.         } else {
  4745.             addresses = url.substr( 7 );
  4746.         }
  4747.  
  4748.         // Let's try to unescape it using a character set
  4749.         // in case the address is not ASCII.
  4750.         try {
  4751.           var characterSet = this.target.ownerDocument.characterSet;
  4752.           const textToSubURI = Components.classes["@mozilla.org/intl/texttosuburi;1"]
  4753.                                          .getService(Components.interfaces.nsITextToSubURI);
  4754.           addresses = textToSubURI.unEscapeURIForUI(characterSet, addresses);
  4755.         }
  4756.         catch(ex) {
  4757.           // Do nothing.
  4758.         }
  4759.  
  4760.         var clipboard = this.getService( "@mozilla.org/widget/clipboardhelper;1",
  4761.                                          Components.interfaces.nsIClipboardHelper );
  4762.         clipboard.copyString(addresses);
  4763.     },
  4764.     addBookmark : function() {
  4765.       var docshell = document.getElementById( "content" ).webNavigation;
  4766. //@line 5197 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4767.       BookmarksUtils.addBookmark( docshell.currentURI.spec,
  4768.                                   docshell.document.title,
  4769.                                   docshell.document.charset,
  4770.                                   BookmarksUtils.getDescriptionFromDocument(docshell.document));
  4771. //@line 5204 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4772.     },
  4773.     addBookmarkForFrame : function() {
  4774. //@line 5207 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4775.       var doc = this.target.ownerDocument;
  4776.       var uri = doc.location.href;
  4777.       var title = doc.title;
  4778.       var description = BookmarksUtils.getDescriptionFromDocument(doc);
  4779.       if ( !title )
  4780.         title = uri;
  4781.       BookmarksUtils.addBookmark(uri, title, doc.charset, description);
  4782. //@line 5217 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  4783.     },
  4784.     // Open Metadata window for node
  4785.     showMetadata : function () {
  4786.         window.openDialog(  "chrome://browser/content/metaData.xul",
  4787.                             "_blank",
  4788.                             "scrollbars,resizable,chrome,dialog=no",
  4789.                             this.target);
  4790.     },
  4791.  
  4792.     ///////////////
  4793.     // Utilities //
  4794.     ///////////////
  4795.  
  4796.     // Create instance of component given contractId and iid (as string).
  4797.     createInstance : function ( contractId, iidName ) {
  4798.         var iid = Components.interfaces[ iidName ];
  4799.         return Components.classes[ contractId ].createInstance( iid );
  4800.     },
  4801.     // Get service given contractId and iid (as string).
  4802.     getService : function ( contractId, iidName ) {
  4803.         var iid = Components.interfaces[ iidName ];
  4804.         return Components.classes[ contractId ].getService( iid );
  4805.     },
  4806.     // Show/hide one item (specified via name or the item element itself).
  4807.     showItem : function ( itemOrId, show ) {
  4808.         // var item = itemOrId.constructor == String ? document.getElementById(itemOrId) : itemOrId;
  4809.         var item = document.getElementById(itemOrId);
  4810.         if (item)
  4811.           item.hidden = !show;
  4812.     },
  4813.     // Set given attribute of specified context-menu item.  If the
  4814.     // value is null, then it removes the attribute (which works
  4815.     // nicely for the disabled attribute).
  4816.     setItemAttr : function ( id, attr, val ) {
  4817.         var elem = document.getElementById( id );
  4818.         if ( elem ) {
  4819.             if ( val == null ) {
  4820.                 // null indicates attr should be removed.
  4821.                 elem.removeAttribute( attr );
  4822.             } else {
  4823.                 // Set attr=val.
  4824.                 elem.setAttribute( attr, val );
  4825.             }
  4826.         }
  4827.     },
  4828.     // Set context menu attribute according to like attribute of another node
  4829.     // (such as a broadcaster).
  4830.     setItemAttrFromNode : function ( item_id, attr, other_id ) {
  4831.         var elem = document.getElementById( other_id );
  4832.         if ( elem && elem.getAttribute( attr ) == "true" ) {
  4833.             this.setItemAttr( item_id, attr, "true" );
  4834.         } else {
  4835.             this.setItemAttr( item_id, attr, null );
  4836.         }
  4837.     },
  4838.     // Temporary workaround for DOM api not yet implemented by XUL nodes.
  4839.     cloneNode : function ( item ) {
  4840.         // Create another element like the one we're cloning.
  4841.         var node = document.createElement( item.tagName );
  4842.  
  4843.         // Copy attributes from argument item to the new one.
  4844.         var attrs = item.attributes;
  4845.         for ( var i = 0; i < attrs.length; i++ ) {
  4846.             var attr = attrs.item( i );
  4847.             node.setAttribute( attr.nodeName, attr.nodeValue );
  4848.         }
  4849.  
  4850.         // Voila!
  4851.         return node;
  4852.     },
  4853.     // Generate fully qualified URL for clicked-on link.
  4854.     getLinkURL : function () {
  4855.         var href = this.link.href;
  4856.         
  4857.         if (href) {
  4858.           return href;
  4859.         }
  4860.  
  4861.         var href = this.link.getAttributeNS("http://www.w3.org/1999/xlink",
  4862.                                           "href");
  4863.  
  4864.         if (!href || !href.match(/\S/)) {
  4865.           throw "Empty href"; // Without this we try to save as the current doc, for example, HTML case also throws if empty
  4866.         }
  4867.         href = makeURLAbsolute(this.link.baseURI, href);
  4868.         return href;
  4869.     },
  4870.     
  4871.     getLinkURI : function () {
  4872.          var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  4873.          try {
  4874.            return ioService.newURI(this.linkURL, null, null);
  4875.          } catch (ex) {
  4876.            // e.g. empty URL string
  4877.            return null;
  4878.          }
  4879.     },
  4880.     
  4881.     getLinkProtocol : function () {
  4882.         if (this.linkURI) {
  4883.             return this.linkURI.scheme; // can be |undefined|
  4884.         } else {
  4885.             return null;
  4886.         }
  4887.     },
  4888.  
  4889.     // Get text of link.
  4890.     linkText : function () {
  4891.         var text = gatherTextUnder( this.link );
  4892.         if (!text || !text.match(/\S/)) {
  4893.           text = this.link.getAttribute("title");
  4894.           if (!text || !text.match(/\S/)) {
  4895.             text = this.link.getAttribute("alt");
  4896.             if (!text || !text.match(/\S/)) {
  4897.               text = this.linkURL;
  4898.             }
  4899.           }
  4900.         }
  4901.  
  4902.         return text;
  4903.     },
  4904.  
  4905.     // Get selected text. Only display the first 15 chars.
  4906.     isTextSelection : function() {
  4907.       // Get 16 characters, so that we can trim the selection if it's greater
  4908.       // than 15 chars
  4909.       var selectedText = getBrowserSelection(16);
  4910.  
  4911.       if (!selectedText)
  4912.         return false;
  4913.  
  4914.       if (selectedText.length > 15)
  4915.         selectedText = selectedText.substr(0,15) + "...";
  4916.  
  4917.       // Use the current engine if the search bar is visible, the default
  4918.       // engine otherwise.
  4919.       var engineName = "";
  4920.       var ss = Cc["@mozilla.org/browser/search-service;1"].
  4921.                getService(Ci.nsIBrowserSearchService);
  4922.       if (BrowserSearch.getSearchBar())
  4923.         engineName = ss.currentEngine.name;
  4924.       else
  4925.         engineName = ss.defaultEngine.name;
  4926.  
  4927.       // format "Search <engine> for <selection>" string to show in menu
  4928.       var menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearchText",
  4929.                                                           [engineName,
  4930.                                                            selectedText]);
  4931.       this.setItemAttr("context-searchselect", "label", menuLabel);
  4932.  
  4933.       return true;
  4934.     },
  4935.  
  4936.     // Returns true if anything is selected.
  4937.     isContentSelection : function() {
  4938.         return !document.commandDispatcher.focusedWindow.getSelection().isCollapsed;
  4939.     },
  4940.  
  4941.     toString : function () {
  4942.         return "contextMenu.target     = " + this.target + "\n" +
  4943.                "contextMenu.onImage    = " + this.onImage + "\n" +
  4944.                "contextMenu.onLink     = " + this.onLink + "\n" +
  4945.                "contextMenu.link       = " + this.link + "\n" +
  4946.                "contextMenu.inFrame    = " + this.inFrame + "\n" +
  4947.                "contextMenu.hasBGImage = " + this.hasBGImage + "\n";
  4948.     },
  4949.  
  4950.     isTargetATextBox : function ( node )
  4951.     {
  4952.       if (node instanceof HTMLInputElement)
  4953.         return (node.type == "text" || node.type == "password")
  4954.  
  4955.       return (node instanceof HTMLTextAreaElement);
  4956.     },
  4957.     isTargetAKeywordField : function ( node )
  4958.     {
  4959.       var form = node.form;
  4960.       if (!form)
  4961.         return false;
  4962.       var method = form.method.toUpperCase();
  4963.  
  4964.       // These are the following types of forms we can create keywords for:
  4965.       //
  4966.       // method   encoding type       can create keyword
  4967.       // GET      *                                 YES
  4968.       //          *                                 YES
  4969.       // POST                                       YES
  4970.       // POST     application/x-www-form-urlencoded YES
  4971.       // POST     text/plain                        NO (a little tricky to do)
  4972.       // POST     multipart/form-data               NO
  4973.       // POST     everything else                   YES
  4974.       return (method == "GET" || method == "") ||
  4975.              (form.enctype != "text/plain") && (form.enctype != "multipart/form-data");
  4976.     },
  4977.  
  4978.     // Determines whether or not the separator with the specified ID should be
  4979.     // shown or not by determining if there are any non-hidden items between it
  4980.     // and the previous separator.
  4981.     shouldShowSeparator : function ( aSeparatorID )
  4982.     {
  4983.       var separator = document.getElementById(aSeparatorID);
  4984.       if (separator) {
  4985.         var sibling = separator.previousSibling;
  4986.         while (sibling && sibling.localName != "menuseparator") {
  4987.           if (sibling.getAttribute("hidden") != "true")
  4988.             return true;
  4989.           sibling = sibling.previousSibling;
  4990.         }
  4991.       }
  4992.       return false;
  4993.     },
  4994.  
  4995.     addDictionaries : function()
  4996.     {
  4997.       var uri = formatURL("browser.dictionaries.download.url", true);
  4998.  
  4999.       var locale = "-";
  5000.       try {
  5001.         locale = gPrefService.getComplexValue("intl.accept_languages",
  5002.                                 Components.interfaces.nsIPrefLocalizedString).data;
  5003.       }
  5004.       catch (e) { }
  5005.  
  5006.       var version = "-";
  5007.       try {
  5008.         version = Components.classes["@mozilla.org/xre/app-info;1"]
  5009.                             .getService(Components.interfaces.nsIXULAppInfo)
  5010.                             .version;
  5011.       }
  5012.       catch (e) { }
  5013.  
  5014.       uri = uri.replace(/%LOCALE%/, escape(locale));
  5015.       uri = uri.replace(/%VERSION%/, version);
  5016.  
  5017.       var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
  5018.       var where = newWindowPref == 3 ? "tab" : "window";
  5019.  
  5020.       openUILinkIn(uri, where);
  5021.     }
  5022. }
  5023.  
  5024. /**
  5025.  * Gets the selected text in the active browser. Leading and trailing
  5026.  * whitespace is removed, and consecutive whitespace is replaced by a single
  5027.  * space. A maximum of 150 characters will be returned, regardless of the value
  5028.  * of aCharLen.
  5029.  *
  5030.  * @param aCharLen
  5031.  *        The maximum number of characters to return.
  5032.  */
  5033. function getBrowserSelection(aCharLen) {
  5034.   // selections of more than 150 characters aren't useful
  5035.   const kMaxSelectionLen = 150;
  5036.   const charLen = Math.min(aCharLen || kMaxSelectionLen, kMaxSelectionLen);
  5037.  
  5038.   var focusedWindow = document.commandDispatcher.focusedWindow;
  5039.   var selection = focusedWindow.getSelection().toString();
  5040.  
  5041.   if (selection) {
  5042.     if (selection.length > charLen) {
  5043.       // only use the first charLen important chars. see bug 221361
  5044.       var pattern = new RegExp("^(?:\\s*.){0," + charLen + "}");
  5045.       pattern.test(selection);
  5046.       selection = RegExp.lastMatch;
  5047.     }
  5048.  
  5049.     selection = selection.replace(/^\s+/, "")
  5050.                          .replace(/\s+$/, "")
  5051.                          .replace(/\s+/g, " ");
  5052.  
  5053.     if (selection.length > charLen)
  5054.       selection = selection.substr(0, charLen);
  5055.   }
  5056.   return selection;
  5057. }
  5058.  
  5059. var gWebPanelURI;
  5060. function openWebPanel(aTitle, aURI)
  5061. {
  5062.     // Ensure that the web panels sidebar is open.
  5063.     toggleSidebar('viewWebPanelsSidebar', true);
  5064.  
  5065.     // Set the title of the panel.
  5066.     document.getElementById("sidebar-title").value = aTitle;
  5067.  
  5068.     // Tell the Web Panels sidebar to load the bookmark.
  5069.     var sidebar = document.getElementById("sidebar");
  5070.     if (sidebar.docShell && sidebar.contentDocument && sidebar.contentDocument.getElementById('web-panels-browser')) {
  5071.         sidebar.contentWindow.loadWebPanel(aURI);
  5072.         if (gWebPanelURI) {
  5073.             gWebPanelURI = "";
  5074.             sidebar.removeEventListener("load", asyncOpenWebPanel, true);
  5075.         }
  5076.     }
  5077.     else {
  5078.         // The panel is still being constructed.  Attach an onload handler.
  5079.         if (!gWebPanelURI)
  5080.             sidebar.addEventListener("load", asyncOpenWebPanel, true);
  5081.         gWebPanelURI = aURI;
  5082.     }
  5083. }
  5084.  
  5085. function asyncOpenWebPanel(event)
  5086. {
  5087.     var sidebar = document.getElementById("sidebar");
  5088.     if (gWebPanelURI && sidebar.contentDocument && sidebar.contentDocument.getElementById('web-panels-browser'))
  5089.         sidebar.contentWindow.loadWebPanel(gWebPanelURI);
  5090.     gWebPanelURI = "";
  5091.     sidebar.removeEventListener("load", asyncOpenWebPanel, true);
  5092. }
  5093.  
  5094. /*
  5095.  * - [ Dependencies ] ---------------------------------------------------------
  5096.  *  utilityOverlay.js:
  5097.  *    - gatherTextUnder
  5098.  */
  5099.  
  5100.  // Called whenever the user clicks in the content area,
  5101.  // except when left-clicking on links (special case)
  5102.  // should always return true for click to go through
  5103.  function contentAreaClick(event, fieldNormalClicks)
  5104.  {
  5105.    if (!event.isTrusted) {
  5106.      return true;
  5107.    }
  5108.  
  5109.    var target = event.target;
  5110.    var linkNode;
  5111.  
  5112.    if (target instanceof HTMLAnchorElement ||
  5113.        target instanceof HTMLAreaElement ||
  5114.        target instanceof HTMLLinkElement) {
  5115.      if (target.hasAttribute("href"))
  5116.        linkNode = target;
  5117.  
  5118.      // xxxmpc: this is kind of a hack to work around a Gecko bug (see bug 266932)
  5119.      // we're going to walk up the DOM looking for a parent link node,
  5120.      // this shouldn't be necessary, but we're matching the existing behaviour for left click
  5121.      var parent = target.parentNode;
  5122.      while (parent) {
  5123.        if (parent instanceof HTMLAnchorElement ||
  5124.            parent instanceof HTMLAreaElement ||
  5125.            parent instanceof HTMLLinkElement) {
  5126.            if (parent.hasAttribute("href"))
  5127.              linkNode = parent;
  5128.        }
  5129.        parent = parent.parentNode;
  5130.      }
  5131.    }
  5132.    else {
  5133.      linkNode = event.originalTarget;
  5134.      while (linkNode && !(linkNode instanceof HTMLAnchorElement))
  5135.        linkNode = linkNode.parentNode;
  5136.      // <a> cannot be nested.  So if we find an anchor without an
  5137.      // href, there is no useful <a> around the target
  5138.      if (linkNode && !linkNode.hasAttribute("href"))
  5139.        linkNode = null;
  5140.    }
  5141.    var wrapper = null;
  5142.    if (linkNode) {
  5143.      wrapper = linkNode;
  5144.      if (event.button == 0 && !event.ctrlKey && !event.shiftKey &&
  5145.          !event.altKey && !event.metaKey) {
  5146.        // A Web panel's links should target the main content area.  Do this
  5147.        // if no modifier keys are down and if there's no target or the target equals
  5148.        // _main (the IE convention) or _content (the Mozilla convention).
  5149.        // XXX Now that markLinkVisited is gone, we may not need to field _main and
  5150.        // _content here.
  5151.        target = wrapper.getAttribute("target");
  5152.        var docWrapper = wrapper.ownerDocument;
  5153.        var locWrapper = docWrapper.location;
  5154.        if (fieldNormalClicks &&
  5155.            (!target || target == "_content" || target  == "_main"))
  5156.          // IE uses _main, SeaMonkey uses _content, we support both
  5157.        {
  5158.          if (!wrapper.href)
  5159.            return true;
  5160.          if (wrapper.getAttribute("onclick"))
  5161.            return true;
  5162.          // javascript links should be executed in the current browser
  5163.          if (wrapper.href.substr(0, 11) === "javascript:")
  5164.            return true;
  5165.          // data links should be executed in the current browser
  5166.          if (wrapper.href.substr(0, 5) === "data:")
  5167.            return true;
  5168.  
  5169.          if (!webPanelSecurityCheck(locWrapper.href, wrapper.href))
  5170.            return false;
  5171.  
  5172.          var postData = { };
  5173.          var url = getShortcutOrURI(wrapper.href, postData);
  5174.          if (!url)
  5175.            return true;
  5176.          loadURI(url, null, postData.value, false);
  5177.          event.preventDefault();
  5178.          return false;
  5179.        }
  5180.        else if (linkNode.getAttribute("rel") == "sidebar") {
  5181.          // This is the Opera convention for a special link that - when clicked - allows
  5182.          // you to add a sidebar panel.  We support the Opera convention here.  The link's
  5183.          // title attribute contains the title that should be used for the sidebar panel.
  5184.          var dialogArgs = {
  5185.            name: wrapper.getAttribute("title"),
  5186.            url: wrapper.href,
  5187.            bWebPanel: true
  5188.          }
  5189. //@line 5624 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5190.          openDialog("chrome://browser/content/bookmarks/addBookmark2.xul", "",
  5191.                     BROWSER_ADD_BM_FEATURES, dialogArgs);
  5192.          event.preventDefault();
  5193. //@line 5630 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5194.          return false;
  5195.        }
  5196.        else if (target == "_search") {
  5197.          // Used in WinIE as a way of transiently loading pages in a sidebar.  We
  5198.          // mimic that WinIE functionality here and also load the page transiently.
  5199.  
  5200.          // javascript links targeting the sidebar shouldn't be allowed
  5201.          // we copied this from IE, and IE blocks this completely
  5202.          if (wrapper.href.substr(0, 11) === "javascript:")
  5203.            return false;
  5204.  
  5205.          // data: URIs are just as dangerous
  5206.          if (wrapper.href.substr(0, 5) === "data:")
  5207.            return false;
  5208.  
  5209.          if (!webPanelSecurityCheck(locWrapper.href, wrapper.href))
  5210.            return false;
  5211.  
  5212.          openWebPanel(gNavigatorBundle.getString("webPanels"), wrapper.href);
  5213.          event.preventDefault();
  5214.          return false;
  5215.        }
  5216.      }
  5217.      else {
  5218.        handleLinkClick(event, wrapper.href, linkNode);
  5219.      }
  5220.  
  5221.      return true;
  5222.    } else {
  5223.      // Try simple XLink
  5224.      var href, realHref, baseURI;
  5225.      linkNode = target;
  5226.      while (linkNode) {
  5227.        if (linkNode.nodeType == Node.ELEMENT_NODE) {
  5228.          wrapper = linkNode;
  5229.  
  5230.          realHref = wrapper.getAttributeNS("http://www.w3.org/1999/xlink", "href");
  5231.          if (realHref) {
  5232.            href = realHref;
  5233.            baseURI = wrapper.baseURI
  5234.          }
  5235.        }
  5236.        linkNode = linkNode.parentNode;
  5237.      }
  5238.      if (href) {
  5239.        href = makeURLAbsolute(baseURI, href);
  5240.        handleLinkClick(event, href, null);
  5241.        return true;
  5242.      }
  5243.    }
  5244.    if (event.button == 1 &&
  5245.        !event.getPreventDefault() &&
  5246.        gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
  5247.        !gPrefService.getBoolPref("general.autoScroll")) {
  5248.      middleMousePaste(event);
  5249.    }
  5250.    return true;
  5251.  }
  5252.  
  5253. function handleLinkClick(event, href, linkNode)
  5254. {
  5255.   var docURL = event.target.ownerDocument.location.href;
  5256.  
  5257.   switch (event.button) {
  5258.     case 0:
  5259. //@line 5698 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5260.       if (event.ctrlKey) {
  5261. //@line 5700 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5262.         openNewTabWith(href, docURL, null, event, false);
  5263.         event.stopPropagation();
  5264.         return true;
  5265.       }
  5266.                                                        // if left button clicked
  5267. //@line 5706 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5268.       if (event.shiftKey && event.altKey) {
  5269.         var feedService = 
  5270.             Cc["@mozilla.org/browser/feeds/result-service;1"].
  5271.             getService(Ci.nsIFeedResultService);
  5272.         feedService.forcePreviewPage = true;
  5273.         loadURI(href, null, null, false);
  5274.         return false;
  5275.       }
  5276. //@line 5715 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5277.                                                        
  5278.       if (event.shiftKey) {
  5279.         openNewWindowWith(href, docURL, null, false);
  5280.         event.stopPropagation();
  5281.         return true;
  5282.       }
  5283.  
  5284.       if (event.altKey) {
  5285.         saveURL(href, linkNode ? gatherTextUnder(linkNode) : "", null, true,
  5286.                 true, makeURI(docURL, event.target.ownerDocument.characterSet));
  5287.         return true;
  5288.       }
  5289.  
  5290.       return false;
  5291.     case 1:                                                         // if middle button clicked
  5292.       var tab;
  5293.       try {
  5294.         tab = gPrefService.getBoolPref("browser.tabs.opentabfor.middleclick")
  5295.       }
  5296.       catch(ex) {
  5297.         tab = true;
  5298.       }
  5299.       if (tab)
  5300.         openNewTabWith(href, docURL, null, event, false);
  5301.       else
  5302.         openNewWindowWith(href, docURL, null, false);
  5303.       event.stopPropagation();
  5304.       return true;
  5305.   }
  5306.   return false;
  5307. }
  5308.  
  5309. function middleMousePaste(event)
  5310. {
  5311.   var url = readFromClipboard();
  5312.   if (!url)
  5313.     return;
  5314.   var postData = { };
  5315.   url = getShortcutOrURI(url, postData);
  5316.   if (!url)
  5317.     return;
  5318.  
  5319.   try {
  5320.     addToUrlbarHistory(url);
  5321.   } catch (ex) {
  5322.     // Things may go wrong when adding url to session history,
  5323.     // but don't let that interfere with the loading of the url.
  5324.   }
  5325.  
  5326.   openUILink(url,
  5327.              event,
  5328.              true /* ignore the fact this is a middle click */);
  5329.  
  5330.   event.stopPropagation();
  5331. }
  5332.  
  5333. function makeURLAbsolute( base, url )
  5334. {
  5335.   // Construct nsIURL.
  5336.   var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  5337.                 .getService(Components.interfaces.nsIIOService);
  5338.   var baseURI  = ioService.newURI(base, null, null);
  5339.  
  5340.   return ioService.newURI(baseURI.resolve(url), null, null).spec;
  5341. }
  5342.  
  5343. /*
  5344.  * Note that most of this routine has been moved into C++ in order to
  5345.  * be available for all <browser> tags as well as gecko embedding. See
  5346.  * mozilla/content/base/src/nsContentAreaDragDrop.cpp.
  5347.  *
  5348.  * Do not add any new fuctionality here other than what is needed for
  5349.  * a standalone product.
  5350.  */
  5351.  
  5352. var contentAreaDNDObserver = {
  5353.   onDrop: function (aEvent, aXferData, aDragSession)
  5354.     {
  5355.       var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
  5356.  
  5357.       // valid urls don't contain spaces ' '; if we have a space it
  5358.       // isn't a valid url, or if it's a javascript: or data: url,
  5359.       // bail out
  5360.       if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
  5361.           /^\s*(javascript|data):/.test(url))
  5362.         return;
  5363.  
  5364.       getBrowser().dragDropSecurityCheck(aEvent, aDragSession, url);
  5365.  
  5366.       switch (document.documentElement.getAttribute('windowtype')) {
  5367.         case "navigator:browser":
  5368.           var postData = { };
  5369.           var uri = getShortcutOrURI(url, postData);
  5370.           loadURI(uri, null, postData.value, false);
  5371.           break;
  5372.         case "navigator:view-source":
  5373.           viewSource(url);
  5374.           break;
  5375.       }
  5376.  
  5377.       // keep the event from being handled by the dragDrop listeners
  5378.       // built-in to gecko if they happen to be above us.
  5379.       aEvent.preventDefault();
  5380.     },
  5381.  
  5382.   getSupportedFlavours: function ()
  5383.     {
  5384.       var flavourSet = new FlavourSet();
  5385.       flavourSet.appendFlavour("text/x-moz-url");
  5386.       flavourSet.appendFlavour("text/unicode");
  5387.       flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
  5388.       return flavourSet;
  5389.     }
  5390.  
  5391. };
  5392.  
  5393. // For extensions
  5394. function getBrowser()
  5395. {
  5396.   if (!gBrowser)
  5397.     gBrowser = document.getElementById("content");
  5398.   return gBrowser;
  5399. }
  5400.  
  5401. function MultiplexHandler(event)
  5402. { try {
  5403.     var node = event.target;
  5404.     var name = node.getAttribute('name');
  5405.  
  5406.     if (name == 'detectorGroup') {
  5407.         SetForcedDetector(true);
  5408.         SelectDetector(event, false);
  5409.     } else if (name == 'charsetGroup') {
  5410.         var charset = node.getAttribute('id');
  5411.         charset = charset.substring('charset.'.length, charset.length)
  5412.         SetForcedCharset(charset);
  5413.         SetDefaultCharacterSet(charset);
  5414.     } else if (name == 'charsetCustomize') {
  5415.         //do nothing - please remove this else statement, once the charset prefs moves to the pref window
  5416.     } else {
  5417.         SetForcedCharset(node.getAttribute('id'));
  5418.         SetDefaultCharacterSet(node.getAttribute('id'));
  5419.     }
  5420.     } catch(ex) { alert(ex); }
  5421. }
  5422.  
  5423. function SetDefaultCharacterSet(charset)
  5424. {
  5425.     BrowserSetDefaultCharacterSet(charset);
  5426. }
  5427.  
  5428. function SelectDetector(event, doReload)
  5429. {
  5430.     var uri =  event.target.getAttribute("id");
  5431.     var prefvalue = uri.substring('chardet.'.length, uri.length);
  5432.     if ("off" == prefvalue) { // "off" is special value to turn off the detectors
  5433.         prefvalue = "";
  5434.     }
  5435.  
  5436.     try {
  5437.         var pref = Components.classes["@mozilla.org/preferences-service;1"]
  5438.                              .getService(Components.interfaces.nsIPrefBranch);
  5439.         var str =  Components.classes["@mozilla.org/supports-string;1"]
  5440.                              .createInstance(Components.interfaces.nsISupportsString);
  5441.  
  5442.         str.data = prefvalue;
  5443.         pref.setComplexValue("intl.charset.detector",
  5444.                              Components.interfaces.nsISupportsString, str);
  5445.         if (doReload) window.content.location.reload();
  5446.     }
  5447.     catch (ex) {
  5448.         dump("Failed to set the intl.charset.detector preference.\n");
  5449.     }
  5450. }
  5451.  
  5452. function SetForcedDetector(doReload)
  5453. {
  5454.     BrowserSetForcedDetector(doReload);
  5455. }
  5456.  
  5457. function SetForcedCharset(charset)
  5458. {
  5459.     BrowserSetForcedCharacterSet(charset);
  5460. }
  5461.  
  5462. function BrowserSetDefaultCharacterSet(aCharset)
  5463. {
  5464.   // no longer needed; set when setting Force; see bug 79608
  5465. }
  5466.  
  5467. function BrowserSetForcedCharacterSet(aCharset)
  5468. {
  5469.   var docCharset = getBrowser().docShell.QueryInterface(
  5470.                             Components.interfaces.nsIDocCharset);
  5471.   docCharset.charset = aCharset;
  5472.   BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
  5473. }
  5474.  
  5475. function BrowserSetForcedDetector(doReload)
  5476. {
  5477.   getBrowser().documentCharsetInfo.forcedDetector = true;
  5478.   if (doReload)
  5479.     BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
  5480. }
  5481.  
  5482. function UpdateCurrentCharset()
  5483. {
  5484.     var menuitem = null;
  5485.  
  5486.     // exctract the charset from DOM
  5487.     var wnd = document.commandDispatcher.focusedWindow;
  5488.     if ((window == wnd) || (wnd == null)) wnd = window.content;
  5489.     menuitem = document.getElementById('charset.' + wnd.document.characterSet);
  5490.  
  5491.     if (menuitem) {
  5492.         // uncheck previously checked item to workaround Mac checkmark problem
  5493.         // bug 98625
  5494.         if (gPrevCharset) {
  5495.             var pref_item = document.getElementById('charset.' + gPrevCharset);
  5496.             if (pref_item)
  5497.               pref_item.setAttribute('checked', 'false');
  5498.         }
  5499.         menuitem.setAttribute('checked', 'true');
  5500.     }
  5501. }
  5502.  
  5503. function UpdateCharsetDetector()
  5504. {
  5505.     var prefvalue;
  5506.  
  5507.     try {
  5508.         var pref = Components.classes["@mozilla.org/preferences-service;1"]
  5509.                              .getService(Components.interfaces.nsIPrefBranch);
  5510.         prefvalue = pref.getComplexValue("intl.charset.detector",
  5511.                                          Components.interfaces.nsIPrefLocalizedString).data;
  5512.     }
  5513.     catch (ex) {
  5514.         prefvalue = "";
  5515.     }
  5516.  
  5517.     if (prefvalue == "") prefvalue = "off";
  5518.     dump("intl.charset.detector = "+ prefvalue + "\n");
  5519.  
  5520.     prefvalue = 'chardet.' + prefvalue;
  5521.     var menuitem = document.getElementById(prefvalue);
  5522.  
  5523.     if (menuitem) {
  5524.         menuitem.setAttribute('checked', 'true');
  5525.     }
  5526. }
  5527.  
  5528. function UpdateMenus(event)
  5529. {
  5530.     // use setTimeout workaround to delay checkmark the menu
  5531.     // when onmenucomplete is ready then use it instead of oncreate
  5532.     // see bug 78290 for the detail
  5533.     UpdateCurrentCharset();
  5534.     setTimeout(UpdateCurrentCharset, 0);
  5535.     UpdateCharsetDetector();
  5536.     setTimeout(UpdateCharsetDetector, 0);
  5537. }
  5538.  
  5539. function CreateMenu(node)
  5540. {
  5541.   var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  5542.   observerService.notifyObservers(null, "charsetmenu-selected", node);
  5543. }
  5544.  
  5545. function charsetLoadListener (event)
  5546. {
  5547.     var charset = window.content.document.characterSet;
  5548.  
  5549.     if (charset.length > 0 && (charset != gLastBrowserCharset)) {
  5550.         if (!gCharsetMenu)
  5551.           gCharsetMenu = Components.classes['@mozilla.org/rdf/datasource;1?name=charset-menu'].getService().QueryInterface(Components.interfaces.nsICurrentCharsetListener);
  5552.         gCharsetMenu.SetCurrentCharset(charset);
  5553.         gPrevCharset = gLastBrowserCharset;
  5554.         gLastBrowserCharset = charset;
  5555.     }
  5556. }
  5557.  
  5558. /* Begin Page Style Functions */
  5559. function getStyleSheetArray(frame)
  5560. {
  5561.   var styleSheets = frame.document.styleSheets;
  5562.   var styleSheetsArray = new Array(styleSheets.length);
  5563.   for (var i = 0; i < styleSheets.length; i++) {
  5564.     styleSheetsArray[i] = styleSheets[i];
  5565.   }
  5566.   return styleSheetsArray;
  5567. }
  5568.  
  5569. function getAllStyleSheets(frameset)
  5570. {
  5571.   var styleSheetsArray = getStyleSheetArray(frameset);
  5572.   for (var i = 0; i < frameset.frames.length; i++) {
  5573.     var frameSheets = getAllStyleSheets(frameset.frames[i]);
  5574.     styleSheetsArray = styleSheetsArray.concat(frameSheets);
  5575.   }
  5576.   return styleSheetsArray;
  5577. }
  5578.  
  5579. function stylesheetFillPopup(menuPopup)
  5580. {
  5581.   var noStyle = menuPopup.firstChild;
  5582.   var persistentOnly = noStyle.nextSibling;
  5583.   var sep = persistentOnly.nextSibling;
  5584.   while (sep.nextSibling)
  5585.     menuPopup.removeChild(sep.nextSibling);
  5586.  
  5587.   var styleSheets = getAllStyleSheets(window.content);
  5588.   var currentStyleSheets = [];
  5589.   var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
  5590.   var haveAltSheets = false;
  5591.   var altStyleSelected = false;
  5592.  
  5593.   for (var i = 0; i < styleSheets.length; ++i) {
  5594.     var currentStyleSheet = styleSheets[i];
  5595.  
  5596.     // Skip any stylesheets that don't match the screen media type.
  5597.     var media = currentStyleSheet.media.mediaText.toLowerCase();
  5598.     if (media && (media.indexOf("screen") == -1) && (media.indexOf("all") == -1))
  5599.         continue;
  5600.  
  5601.     if (currentStyleSheet.title) {
  5602.       if (!currentStyleSheet.disabled)
  5603.         altStyleSelected = true;
  5604.  
  5605.       haveAltSheets = true;
  5606.  
  5607.       var lastWithSameTitle = null;
  5608.       if (currentStyleSheet.title in currentStyleSheets)
  5609.         lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
  5610.  
  5611.       if (!lastWithSameTitle) {
  5612.         var menuItem = document.createElement("menuitem");
  5613.         menuItem.setAttribute("type", "radio");
  5614.         menuItem.setAttribute("label", currentStyleSheet.title);
  5615.         menuItem.setAttribute("data", currentStyleSheet.title);
  5616.         menuItem.setAttribute("checked", !currentStyleSheet.disabled && !styleDisabled);
  5617.         menuPopup.appendChild(menuItem);
  5618.         currentStyleSheets[currentStyleSheet.title] = menuItem;
  5619.       } else {
  5620.         if (currentStyleSheet.disabled)
  5621.           lastWithSameTitle.removeAttribute("checked");
  5622.       }
  5623.     }
  5624.   }
  5625.  
  5626.   noStyle.setAttribute("checked", styleDisabled);
  5627.   persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
  5628.   persistentOnly.hidden = (window.content.document.preferredStylesheetSet) ? haveAltSheets : false;
  5629.   sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
  5630.   return true;
  5631. }
  5632.  
  5633. function stylesheetInFrame(frame, title) {
  5634.   var docStyleSheets = frame.document.styleSheets;
  5635.  
  5636.   for (var i = 0; i < docStyleSheets.length; ++i) {
  5637.     if (docStyleSheets[i].title == title)
  5638.       return true;
  5639.   }
  5640.   return false;
  5641. }
  5642.  
  5643. function stylesheetSwitchFrame(frame, title) {
  5644.   var docStyleSheets = frame.document.styleSheets;
  5645.  
  5646.   for (var i = 0; i < docStyleSheets.length; ++i) {
  5647.     var docStyleSheet = docStyleSheets[i];
  5648.  
  5649.     if (title == "_nostyle")
  5650.       docStyleSheet.disabled = true;
  5651.     else if (docStyleSheet.title)
  5652.       docStyleSheet.disabled = (docStyleSheet.title != title);
  5653.     else if (docStyleSheet.disabled)
  5654.       docStyleSheet.disabled = false;
  5655.   }
  5656. }
  5657.  
  5658. function stylesheetSwitchAll(frameset, title) {
  5659.   if (!title || title == "_nostyle" || stylesheetInFrame(frameset, title)) {
  5660.     stylesheetSwitchFrame(frameset, title);
  5661.   }
  5662.   for (var i = 0; i < frameset.frames.length; i++) {
  5663.     stylesheetSwitchAll(frameset.frames[i], title);
  5664.   }
  5665. }
  5666.  
  5667. function setStyleDisabled(disabled) {
  5668.   getMarkupDocumentViewer().authorStyleDisabled = disabled;
  5669. }
  5670.  
  5671. //@line 6139 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5672. /* End of the Page Style functions */
  5673.  
  5674. var BrowserOffline = {
  5675.   /////////////////////////////////////////////////////////////////////////////
  5676.   // BrowserOffline Public Methods
  5677.   init: function ()
  5678.   {
  5679.     if (!this._uiElement)
  5680.       this._uiElement = document.getElementById("goOfflineMenuitem");
  5681.  
  5682.     var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  5683.     os.addObserver(this, "network:offline-status-changed", false);
  5684.  
  5685.     var ioService = Components.classes["@mozilla.org/network/io-service;1"].
  5686.       getService(Components.interfaces.nsIIOService2);
  5687.  
  5688.     // if ioService is managing the offline status, then ioservice.offline
  5689.     // is already set correctly. We will continue to allow the ioService
  5690.     // to manage its offline state until the user uses the "Work Offline" UI.
  5691.     
  5692.     if (!ioService.manageOfflineStatus) {
  5693.       // set the initial state
  5694.       var isOffline = false;
  5695.       try {
  5696.         isOffline = gPrefService.getBoolPref("browser.offline");
  5697.       }
  5698.       catch (e) { }
  5699.       ioService.offline = isOffline;
  5700.     }
  5701.     
  5702.     this._updateOfflineUI(ioService.offline);
  5703.   },
  5704.  
  5705.   uninit: function ()
  5706.   {
  5707.     try {
  5708.       var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  5709.       os.removeObserver(this, "network:offline-status-changed");
  5710.     } catch (ex) {
  5711.     }
  5712.   },
  5713.  
  5714.   toggleOfflineStatus: function ()
  5715.   {
  5716.     var ioService = Components.classes["@mozilla.org/network/io-service;1"].
  5717.       getService(Components.interfaces.nsIIOService2);
  5718.  
  5719.     // Stop automatic management of the offline status
  5720.     try {
  5721.       ioService.manageOfflineStatus = false;
  5722.     } catch (ex) {
  5723.     }
  5724.   
  5725.     if (!this._canGoOffline()) {
  5726.       this._updateOfflineUI(false);
  5727.       return;
  5728.     }
  5729.  
  5730.     ioService.offline = !ioService.offline;
  5731.  
  5732.     // Save the current state for later use as the initial state
  5733.     // (if there is no netLinkService)
  5734.     gPrefService.setBoolPref("browser.offline", ioService.offline);
  5735.   },
  5736.  
  5737.   /////////////////////////////////////////////////////////////////////////////
  5738.   // nsIObserver
  5739.   observe: function (aSubject, aTopic, aState)
  5740.   {
  5741.     if (aTopic != "network:offline-status-changed")
  5742.       return;
  5743.  
  5744.     this._updateOfflineUI(aState == "offline");
  5745.   },
  5746.  
  5747.   /////////////////////////////////////////////////////////////////////////////
  5748.   // BrowserOffline Implementation Methods
  5749.   _canGoOffline: function ()
  5750.   {
  5751.     var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  5752.     if (os) {
  5753.       try {
  5754.         var cancelGoOffline = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
  5755.         os.notifyObservers(cancelGoOffline, "offline-requested", null);
  5756.  
  5757.         // Something aborted the quit process.
  5758.         if (cancelGoOffline.data)
  5759.           return false;
  5760.       }
  5761.       catch (ex) {
  5762.       }
  5763.     }
  5764.     return true;
  5765.   },
  5766.  
  5767.   _uiElement: null,
  5768.   _updateOfflineUI: function (aOffline)
  5769.   {
  5770.     var offlineLocked = gPrefService.prefIsLocked("network.online");
  5771.     if (offlineLocked)
  5772.       this._uiElement.setAttribute("disabled", "true");
  5773.  
  5774.     this._uiElement.setAttribute("checked", aOffline);
  5775.   }
  5776. };
  5777.  
  5778. function WindowIsClosing()
  5779. {
  5780.   var browser = getBrowser();
  5781.   var cn = browser.tabContainer.childNodes;
  5782.   var numtabs = cn.length;
  5783.   var reallyClose = browser.warnAboutClosingTabs(true);
  5784.  
  5785.   for (var i = 0; reallyClose && i < numtabs; ++i) {
  5786.     var ds = browser.getBrowserForTab(cn[i]).docShell;
  5787.  
  5788.     if (ds.contentViewer && !ds.contentViewer.permitUnload())
  5789.       reallyClose = false;
  5790.   }
  5791.  
  5792.   if (reallyClose)
  5793.     return closeWindow(false);
  5794.  
  5795.   return reallyClose;
  5796. }
  5797.  
  5798. var MailIntegration = {
  5799.   sendLinkForContent: function () {
  5800.     this.sendMessage(window.content.location.href,
  5801.                      window.content.document.title);
  5802.   },
  5803.  
  5804.   sendMessage: function (aBody, aSubject) {
  5805.     // generate a mailto url based on the url and the url's title
  5806.     var mailtoUrl = "mailto:";
  5807.     if (aBody) {
  5808.       mailtoUrl += "?body=" + encodeURIComponent(aBody);
  5809.       mailtoUrl += "&subject=" + encodeURIComponent(aSubject);
  5810.     }
  5811.  
  5812.     var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  5813.                               .getService(Components.interfaces.nsIIOService);
  5814.     var uri = ioService.newURI(mailtoUrl, null, null);
  5815.  
  5816.     // now pass this uri to the operating system
  5817.     this._launchExternalUrl(uri);
  5818.   },
  5819.  
  5820.   // a generic method which can be used to pass arbitrary urls to the operating
  5821.   // system.
  5822.   // aURL --> a nsIURI which represents the url to launch
  5823.   _launchExternalUrl: function (aURL) {
  5824.     var extProtocolSvc =
  5825.        Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
  5826.                  .getService(Components.interfaces.nsIExternalProtocolService);
  5827.     if (extProtocolSvc)
  5828.       extProtocolSvc.loadUrl(aURL);
  5829.   }
  5830. };
  5831.  
  5832. function BrowserOpenAddonsMgr()
  5833. {
  5834.   const EMTYPE = "Extension:Manager";
  5835.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  5836.                      .getService(Components.interfaces.nsIWindowMediator);
  5837.   var theEM = wm.getMostRecentWindow(EMTYPE);
  5838.   if (theEM) {
  5839.     theEM.focus();
  5840.     return;
  5841.   }
  5842.  
  5843.   const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
  5844.   const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
  5845.   window.openDialog(EMURL, "", EMFEATURES);
  5846. }
  5847.  
  5848. function escapeNameValuePair(aName, aValue, aIsFormUrlEncoded)
  5849. {
  5850.   if (aIsFormUrlEncoded)
  5851.     return escape(aName + "=" + aValue);
  5852.   else
  5853.     return escape(aName) + "=" + escape(aValue);
  5854. }
  5855.  
  5856. function AddKeywordForSearchField()
  5857. {
  5858.   var node = document.popupNode;
  5859.  
  5860.   var docURI = makeURI(node.ownerDocument.URL,
  5861.                        node.ownerDocument.characterSet);
  5862.  
  5863.   var formURI = makeURI(node.form.getAttribute("action"),
  5864.                         node.ownerDocument.characterSet,
  5865.                         docURI);
  5866.  
  5867.   var spec = formURI.spec;
  5868.  
  5869.   var isURLEncoded = 
  5870.                (node.form.method.toUpperCase() == "POST"
  5871.                 && (node.form.enctype == "application/x-www-form-urlencoded" ||
  5872.                     node.form.enctype == ""));
  5873.  
  5874.   var el, type;
  5875.   var formData = [];
  5876.  
  5877.   for (var i=0; i < node.form.elements.length; i++) {
  5878.     el = node.form.elements[i];
  5879.  
  5880.     if (!el.type) // happens with fieldsets
  5881.       continue;
  5882.  
  5883.     if (el == node) {
  5884.       formData.push((isURLEncoded) ? escapeNameValuePair(el.name, "%s", true) :
  5885.                                      // Don't escape "%s", just append
  5886.                                      escapeNameValuePair(el.name, "", false) + "%s");
  5887.       continue;
  5888.     }
  5889.  
  5890.     type = el.type.toLowerCase();
  5891.     
  5892.     if ((type == "text" || type == "hidden" || type == "textarea") ||
  5893.         ((type == "checkbox" || type == "radio") && el.checked)) {
  5894.       formData.push(escapeNameValuePair(el.name, el.value, isURLEncoded));
  5895.     } else if (el instanceof HTMLSelectElement && el.selectedIndex >= 0) {
  5896.       for (var j=0; j < el.options.length; j++) {
  5897.         if (el.options[j].selected)
  5898.           formData.push(escapeNameValuePair(el.name, el.options[j].value,
  5899.                                             isURLEncoded));
  5900.       }
  5901.     }
  5902.   }
  5903.  
  5904.   var postData;
  5905.  
  5906.   if (isURLEncoded)
  5907.     postData = formData.join("&");
  5908.   else
  5909.     spec += "?" + formData.join("&");
  5910.  
  5911. //@line 6379 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5912.   var dialogArgs = {
  5913.     name: "",
  5914.     url: spec,
  5915.     charset: node.ownerDocument.characterSet,
  5916.     bWebPanel: false,
  5917.     keyword: "",
  5918.     bNeedKeyword: true,
  5919.     postData: postData,
  5920.     description: BookmarksUtils.getDescriptionFromDocument(node.ownerDocument)
  5921.   }
  5922.   openDialog("chrome://browser/content/bookmarks/addBookmark2.xul", "",
  5923.              BROWSER_ADD_BM_FEATURES, dialogArgs);
  5924. //@line 6394 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  5925. }
  5926.  
  5927. function SwitchDocumentDirection(aWindow) {
  5928.   aWindow.document.dir = (aWindow.document.dir == "ltr" ? "rtl" : "ltr");
  5929.   for (var run = 0; run < aWindow.frames.length; run++)
  5930.     SwitchDocumentDirection(aWindow.frames[run]);
  5931. }
  5932.  
  5933. function missingPluginInstaller(){
  5934. }
  5935.  
  5936. function getPluginInfo(pluginElement)
  5937. {
  5938.   var tagMimetype;
  5939.   var pluginsPage;
  5940.   if (pluginElement instanceof HTMLAppletElement) {
  5941.     tagMimetype = "application/x-java-vm";
  5942.   } else {
  5943.     if (pluginElement instanceof HTMLObjectElement) {
  5944.       pluginsPage = pluginElement.getAttribute("codebase");
  5945.     } else {
  5946.       pluginsPage = pluginElement.getAttribute("pluginspage");
  5947.     }
  5948.  
  5949.     // only attempt if a pluginsPage is defined.
  5950.     if (pluginsPage) {
  5951.       var doc = pluginElement.ownerDocument;
  5952.       var docShell = findChildShell(doc, gBrowser.selectedBrowser.docShell, null);
  5953.       try {
  5954.         pluginsPage = makeURI(pluginsPage, doc.characterSet, docShell.currentURI).spec;
  5955.       } catch (ex) { 
  5956.         pluginsPage = "";
  5957.       }
  5958.     }
  5959.  
  5960.     tagMimetype = pluginElement.QueryInterface(Components.interfaces.nsIPluginElement).actualType;
  5961.  
  5962.     if (tagMimetype == "") {
  5963.       tagMimetype = pluginElement.type;
  5964.     }
  5965.   }
  5966.  
  5967.   return {mimetype: tagMimetype, pluginsPage: pluginsPage};
  5968. }
  5969.  
  5970. missingPluginInstaller.prototype.installSinglePlugin = function(aEvent){
  5971.   var tabbrowser = getBrowser();
  5972.   var missingPluginsArray = new Object;
  5973.  
  5974.   var pluginInfo = getPluginInfo(aEvent.target);
  5975.   missingPluginsArray[pluginInfo.mimetype] = pluginInfo;
  5976.  
  5977.   if (missingPluginsArray) {
  5978.     window.openDialog("chrome://mozapps/content/plugins/pluginInstallerWizard.xul",
  5979.                       "PFSWindow", "modal,chrome,resizable=yes",
  5980.                       {plugins: missingPluginsArray, tab: tabbrowser.mCurrentTab});
  5981.   }
  5982.  
  5983.   aEvent.preventDefault();
  5984. }
  5985.  
  5986. missingPluginInstaller.prototype.newMissingPlugin = function(aEvent){
  5987.   // For broken non-object plugin tags, register a click handler so
  5988.   // that the user can click the plugin replacement to get the new
  5989.   // plugin. Object tags can, and often do, deal with that themselves,
  5990.   // so don't stomp on the page developers toes.
  5991.  
  5992.   if (!(aEvent.target instanceof HTMLObjectElement)) {
  5993.     aEvent.target.addEventListener("click",
  5994.                                    gMissingPluginInstaller.installSinglePlugin,
  5995.                                    false);
  5996.   }
  5997.  
  5998.   var tabbrowser = getBrowser();
  5999.   const browsers = tabbrowser.mPanelContainer.childNodes;
  6000.  
  6001.   var window = aEvent.target.ownerDocument.defaultView;
  6002.   // walk up till the toplevel window
  6003.   while (window.parent != window)
  6004.     window = window.parent;
  6005.  
  6006.   var i = 0;
  6007.   for (; i < browsers.length; i++) {
  6008.     if (tabbrowser.getBrowserAtIndex(i).contentWindow == window)
  6009.       break;
  6010.   }
  6011.  
  6012.   var tab = tabbrowser.mTabContainer.childNodes[i];
  6013.   if (!tab.missingPlugins)
  6014.     tab.missingPlugins = new Object();
  6015.  
  6016.   var pluginInfo = getPluginInfo(aEvent.target);
  6017.  
  6018.   tab.missingPlugins[pluginInfo.mimetype] = pluginInfo;
  6019.  
  6020.   var browser = tabbrowser.getBrowserAtIndex(i);
  6021.   var notificationBox = gBrowser.getNotificationBox(browser);
  6022.   if (!notificationBox.getNotificationWithValue("missing-plugins")) {
  6023.     var bundle_browser = document.getElementById("bundle_browser");
  6024.     var messageString = bundle_browser.getString("missingpluginsMessage.title");
  6025.     var buttons = [{
  6026.       label: bundle_browser.getString("missingpluginsMessage.button.label"),
  6027.       accessKey: bundle_browser.getString("missingpluginsMessage.button.accesskey"),
  6028.       popup: null,
  6029.       callback: pluginsMissing
  6030.     }];
  6031.  
  6032.     const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
  6033.     const iconURL = "chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
  6034.     notificationBox.appendNotification(messageString, "missing-plugins",
  6035.                                        iconURL, priority, buttons);
  6036.   }
  6037. }
  6038.  
  6039. missingPluginInstaller.prototype.closeNotification = function() {
  6040.   var notificationBox = gBrowser.getNotificationBox();
  6041.   var notification = notificationBox.getNotificationWithValue("missing-plugins");
  6042.  
  6043.   if (notification) {
  6044.     notificationBox.removeNotification(notification);
  6045.   }
  6046. }
  6047.  
  6048. function pluginsMissing()
  6049. {
  6050.   // get the urls of missing plugins
  6051.   var tabbrowser = getBrowser();
  6052.   var missingPluginsArray = tabbrowser.mCurrentTab.missingPlugins;
  6053.   if (missingPluginsArray) {
  6054.     window.openDialog("chrome://mozapps/content/plugins/pluginInstallerWizard.xul",
  6055.       "PFSWindow", "modal,chrome,resizable=yes", {plugins: missingPluginsArray, tab: tabbrowser.mCurrentTab});
  6056.   }
  6057. }
  6058.  
  6059. var gMissingPluginInstaller = new missingPluginInstaller();
  6060.  
  6061. function convertFromUnicode(charset, str)
  6062. {
  6063.   try {
  6064.     var unicodeConverter = Components
  6065.        .classes["@mozilla.org/intl/scriptableunicodeconverter"]
  6066.        .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  6067.     unicodeConverter.charset = charset;
  6068.     str = unicodeConverter.ConvertFromUnicode(str);
  6069.     return str + unicodeConverter.Finish();
  6070.   } catch(ex) {
  6071.     return null; 
  6072.   }
  6073. }
  6074.  
  6075. /**
  6076.  * The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
  6077.  * and shows UI when they are discovered. 
  6078.  */
  6079. var FeedHandler = {
  6080.   /**
  6081.    * Initialize the Feed Handler
  6082.    */
  6083.   init: function() {
  6084.     gBrowser.addEventListener("DOMLinkAdded", 
  6085.                               function (event) { FeedHandler.onLinkAdded(event); }, 
  6086.                               true);
  6087.     gBrowser.addEventListener("pagehide", FeedHandler.onPageHide, true);
  6088.   },
  6089.   
  6090.   onPageHide: function(event) {
  6091.     var theBrowser = gBrowser.getBrowserForDocument(event.target);
  6092.     if (theBrowser)
  6093.       theBrowser.feeds = null;
  6094.   },
  6095.   
  6096.   /**
  6097.    * The click handler for the Feed icon in the location bar. Opens the
  6098.    * subscription page if user is not given a choice of feeds.
  6099.    * (Otherwise the list of available feeds will be presented to the 
  6100.    * user in a popup menu.)
  6101.    */
  6102.   onFeedButtonClick: function(event) {
  6103.     event.stopPropagation();
  6104.  
  6105.     if (event.target.hasAttribute("feed") &&
  6106.         event.eventPhase == Event.AT_TARGET &&
  6107.         (event.button == 0 || event.button == 1)) {
  6108.         this.subscribeToFeed(null, event);
  6109.     }
  6110.   },
  6111.   
  6112.   /**
  6113.    * Called when the user clicks on the Feed icon in the location bar. 
  6114.    * Builds a menu of unique feeds associated with the page, and if there
  6115.    * is only one, shows the feed inline in the browser window. 
  6116.    * @param   menuPopup
  6117.    *          The feed list menupopup to be populated.
  6118.    * @returns true if the menu should be shown, false if there was only
  6119.    *          one feed and the feed should be shown inline in the browser
  6120.    *          window (do not show the menupopup).
  6121.    */
  6122.   buildFeedList: function(menuPopup) {
  6123.     var feeds = gBrowser.selectedBrowser.feeds;
  6124.     if (feeds == null) {
  6125.       // XXX hack -- menu opening depends on setting of an "open"
  6126.       // attribute, and the menu refuses to open if that attribute is
  6127.       // set (because it thinks it's already open).  onpopupshowing gets
  6128.       // called after the attribute is unset, and it doesn't get unset
  6129.       // if we return false.  so we unset it here; otherwise, the menu
  6130.       // refuses to work past this point.
  6131.       menuPopup.parentNode.removeAttribute("open");
  6132.       return false;
  6133.     }
  6134.  
  6135.     while (menuPopup.firstChild)
  6136.       menuPopup.removeChild(menuPopup.firstChild);
  6137.     
  6138.     // Get the list of unique feeds, and if there's only one unique entry, 
  6139.     // show the feed in the browser rather than displaying a menu. 
  6140.     var feeds = this.harvestFeeds(feeds);
  6141.     if (feeds.length == 1)
  6142.       return false;
  6143.  
  6144.     // Build the menu showing the available feed choices for viewing. 
  6145.     for (var i = 0; i < feeds.length; ++i) {
  6146.       var feedInfo = feeds[i];
  6147.       var menuItem = document.createElement("menuitem");
  6148.       var baseTitle = feedInfo.title || feedInfo.href;
  6149. //@line 6619 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6150.       var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
  6151. //@line 6623 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6152.       menuItem.setAttribute("label", labelStr);
  6153.       menuItem.setAttribute("feed", feedInfo.href);
  6154.       menuItem.setAttribute("tooltiptext", feedInfo.href);
  6155.       menuPopup.appendChild(menuItem);
  6156.     }
  6157.     return true;
  6158.   },
  6159.   
  6160.   /**
  6161.    * Subscribe to a given feed.  Called when
  6162.    *   1. Page has a single feed and user clicks feed icon in location bar
  6163.    *   2. Page has a single feed and user selects Subscribe menu item
  6164.    *   3. Page has multiple feeds and user selects from feed icon popup
  6165.    *   4. Page has multiple feeds and user selects from Subscribe submenu
  6166.    * @param   href
  6167.    *          The feed to subscribe to. May be null, in which case the
  6168.    *          event target's feed attribute is examined.
  6169.    * @param   event
  6170.    *          The event this method is handling. Used to decide where 
  6171.    *          to open the preview UI. (Optional, unless href is null)
  6172.    */
  6173.   subscribeToFeed: function(href, event) {
  6174. //@line 6646 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6175.       // Just load the feed in the content area to either subscribe or show the
  6176.       // preview UI
  6177.       if (!href)
  6178.         href = event.target.getAttribute("feed");
  6179.       urlSecurityCheck(href, gBrowser.currentURI.spec,
  6180.                        Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT_OR_DATA);
  6181.       var feedURI = makeURI(href, document.characterSet);
  6182.       // Use the feed scheme so X-Moz-Is-Feed will be set
  6183.       // The value doesn't matter
  6184.       if (/^https?/.test(feedURI.scheme))
  6185.         href = "feed:" + href;
  6186.       this.loadFeed(href, event);
  6187. //@line 6669 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6188.   },
  6189.  
  6190.   /**
  6191.    * Attempt to generate a list of unique feeds from the list of feeds
  6192.    * supplied by the web page. It is fairly common for a site to supply
  6193.    * feeds in multiple formats but with divergent |title| attributes so
  6194.    * we need to make a rough pass at trying to not show a menu when there
  6195.    * is in fact only one feed. If this is the case, by default select
  6196.    * the ATOM feed if one is supplied, otherwise pick the first one. 
  6197.    * @param   feeds
  6198.    *          An array of Feed info JS Objects representing the list of
  6199.    *          feeds advertised by the web page
  6200.    * @returns An array of what should be mostly unique feeds. 
  6201.    */
  6202.   harvestFeeds: function(feeds) {
  6203.     var feedHash = { };
  6204.     for (var i = 0; i < feeds.length; ++i) {
  6205.       var feed = feeds[i];
  6206.       if (!(feed.type in feedHash))
  6207.         feedHash[feed.type] = [];
  6208.       feedHash[feed.type].push(feed);
  6209.     }
  6210.     var mismatch = false;
  6211.     var count = 0;
  6212.     var defaultType = null;
  6213.     for (var type in feedHash) {
  6214.       // The default type is whichever is listed first on the web page.
  6215.       // Nothing fancy, just something that works.
  6216.       if (!defaultType) {
  6217.         defaultType = type;
  6218.         count = feedHash[type].length;
  6219.       }
  6220.       if (feedHash[type].length != count) {
  6221.         mismatch = true;
  6222.         break;
  6223.       }
  6224.       count = feedHash[type].length;
  6225.     }
  6226.     // There are more feeds of one type than another - this implies the
  6227.     // content developer is supplying multiple channels, let's not do 
  6228.     // anything fancier than this and just return the full set. 
  6229.     if (mismatch)
  6230.       return feeds;
  6231.       
  6232.     // Look for an atom feed by default, fall back to whichever was listed
  6233.     // first if there is no atom feed supplied. 
  6234.     const ATOMTYPE = "application/atom+xml";
  6235.     return ATOMTYPE in feedHash ? feedHash[ATOMTYPE] : feedHash[defaultType];
  6236.   },
  6237.     
  6238.   /**
  6239.    * Locate the shell that has a specified document loaded in it. 
  6240.    * @param   doc
  6241.    *          The document to find a shell for.
  6242.    * @returns The doc shell that contains the specified document.
  6243.    */
  6244.   _getContentShell: function(doc) {
  6245.     var browsers = getBrowser().browsers;
  6246.     for (var i = 0; i < browsers.length; i++) {
  6247.       var shell = findChildShell(doc, browsers[i].docShell, null);
  6248.       if (shell)
  6249.         return { shell: shell, browser: browsers[i] };
  6250.     }
  6251.     return null;
  6252.   },
  6253.   
  6254. //@line 6736 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6255.   /**
  6256.    * Adds a Live Bookmark to a feed
  6257.    * @param     url
  6258.    *            The URL of the feed being bookmarked
  6259.    * @title     title
  6260.    *            The title of the feed. Optional.
  6261.    * @subtitle  subtitle
  6262.    *            A short description of the feed. Optional.
  6263.    */
  6264.   addLiveBookmark: function(url, feedTitle, feedSubtitle) {
  6265.     var doc = gBrowser.selectedBrowser.contentDocument;
  6266.     var title = (arguments.length > 1) ? feedTitle : doc.title;
  6267.     var description;
  6268.     if (arguments.length > 2)
  6269.       description = feedSubtitle;
  6270.     else
  6271.       description = BookmarksUtils.getDescriptionFromDocument(doc);
  6272.     BookmarksUtils.addLivemark(doc.baseURI, url, title, description);
  6273.   },
  6274. //@line 6756 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6275.   
  6276. //@line 6758 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6277.   loadFeed: function(href, event) {
  6278.     var feeds = gBrowser.selectedBrowser.feeds;
  6279.     try {
  6280.       openUILink(href, event, false, true, false, null);
  6281.     }
  6282.     finally {
  6283.       // We might default to a livebookmarks modal dialog, 
  6284.       // so reset that if the user happens to click it again
  6285.       gBrowser.selectedBrowser.feeds = feeds;
  6286.     }
  6287.   },
  6288. //@line 6770 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6289.  
  6290.   /**
  6291.    * Update the browser UI to show whether or not feeds are available when
  6292.    * a page is loaded or the user switches tabs to a page that has feeds. 
  6293.    */
  6294.   updateFeeds: function() {
  6295.     var feedButton = document.getElementById("feed-button");
  6296.     if (!this._feedMenuitem)
  6297.       this._feedMenuitem = document.getElementById("subscribeToPageMenuitem");
  6298.     if (!this._feedMenupopup)
  6299.       this._feedMenupopup = document.getElementById("subscribeToPageMenupopup");
  6300.  
  6301.     var feeds = gBrowser.mCurrentBrowser.feeds;
  6302.     if (!feeds || feeds.length == 0) {
  6303.       if (feedButton) {
  6304.         feedButton.removeAttribute("feeds");
  6305.         feedButton.removeAttribute("feed");
  6306.         feedButton.setAttribute("tooltiptext", 
  6307.                                 gNavigatorBundle.getString("feedNoFeeds"));
  6308.       }
  6309.       this._feedMenuitem.setAttribute("disabled", "true");
  6310.       this._feedMenupopup.setAttribute("hidden", "true");
  6311.       this._feedMenuitem.removeAttribute("hidden");
  6312.     } else {
  6313.       if (feedButton) {
  6314.         feedButton.setAttribute("feeds", "true");
  6315.         feedButton.setAttribute("tooltiptext", 
  6316. //@line 6798 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6317.                               gNavigatorBundle.getString("feedHasFeedsNew"));
  6318. //@line 6802 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6319.       }
  6320.       // check for dupes before we pick which UI to expose
  6321.       feeds = this.harvestFeeds(feeds);
  6322.       
  6323.       if (feeds.length > 1) {
  6324.         this._feedMenuitem.setAttribute("hidden", "true");
  6325.         this._feedMenupopup.removeAttribute("hidden");
  6326.         if (feedButton)
  6327.           feedButton.removeAttribute("feed");
  6328.       } else {
  6329.         if (feedButton)
  6330.           feedButton.setAttribute("feed", feeds[0].href);
  6331.  
  6332.         this._feedMenuitem.setAttribute("feed", feeds[0].href);
  6333.         this._feedMenuitem.removeAttribute("disabled");
  6334.         this._feedMenuitem.removeAttribute("hidden");
  6335.         this._feedMenupopup.setAttribute("hidden", "true");
  6336.       }
  6337.     }
  6338.   }, 
  6339.   
  6340.   /**
  6341.    * A new <link> tag has been discovered - check to see if it advertises
  6342.    * an RSS feed. 
  6343.    */
  6344.   onLinkAdded: function(event) {
  6345.     // XXX this event listener can/should probably be combined with the onLinkAdded
  6346.     // listener in tabbrowser.xml, which only listens for favicons and then passes
  6347.     // them to onLinkIconAvailable in the ProgressListener.  We could extend the
  6348.     // progress listener to have a generic onLinkAvailable and have tabbrowser pass
  6349.     // along all events.  It should give us the browser for the tab, as well as
  6350.     // the actual event.
  6351.  
  6352.     var erel = event.target.rel;
  6353.     var etype = event.target.type;
  6354.     var etitle = event.target.title;
  6355.     const alternateRelRegex = /(^|\s)alternate($|\s)/i;
  6356.     const rssTitleRegex = /(^|\s)rss($|\s)/i;
  6357.  
  6358.     if (!alternateRelRegex.test(erel) ||
  6359.         !etype)
  6360.       return;
  6361.  
  6362.     etype = etype.replace(/^\s+/, "");
  6363.     etype = etype.replace(/\s+$/, "");
  6364.     etype = etype.replace(/\s*;.*/, "");
  6365.     etype = etype.toLowerCase();
  6366.  
  6367.     if (etype == "application/rss+xml" ||
  6368.         etype == "application/atom+xml" ||
  6369.         (etype == "text/xml" ||
  6370.          etype == "application/xml" ||
  6371.          etype == "application/rdf+xml") &&
  6372.         rssTitleRegex.test(etitle))
  6373.     {
  6374.       const targetDoc = event.target.ownerDocument;
  6375.  
  6376.       // find which tab this is for, and set the attribute on the browser
  6377.       var browserForLink = gBrowser.getBrowserForDocument(targetDoc);
  6378.       if (!browserForLink) {
  6379.         // ??? this really shouldn't happen..
  6380.         return;
  6381.       }
  6382.  
  6383.       var feeds = [];
  6384.       if (browserForLink.feeds != null)
  6385.         feeds = browserForLink.feeds;
  6386.       var wrapper = event.target;
  6387.  
  6388.       try { 
  6389.         urlSecurityCheck(wrapper.href, gBrowser.currentURI.spec,
  6390.                          Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT_OR_DATA);
  6391.       }
  6392.       catch (ex) {
  6393.         dump(ex.message);
  6394.         return; // doesn't pass security check
  6395.       }
  6396.  
  6397.       feeds.push({ href: wrapper.href,
  6398.                    type: etype,
  6399.                    title: wrapper.title});
  6400.       browserForLink.feeds = feeds;
  6401.       if (browserForLink == gBrowser || browserForLink == gBrowser.mCurrentBrowser) {
  6402.         var feedButton = document.getElementById("feed-button");
  6403.         if (feedButton) {
  6404.           feedButton.setAttribute("feeds", "true");
  6405.           feedButton.setAttribute("tooltiptext", 
  6406. //@line 6890 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6407.                                   gNavigatorBundle.getString("feedHasFeedsNew"));
  6408. //@line 6894 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6409.         }
  6410.       }
  6411.     }
  6412.   }
  6413. };
  6414.  
  6415. //@line 6967 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6416.  
  6417. /**
  6418.  * This object is for augmenting tabs
  6419.  */
  6420. var AugmentTabs = {
  6421.  
  6422.   tabContextMenu: null,
  6423.   undoCloseTabMenu: null,
  6424.  
  6425.   /**
  6426.    * Called in delayedStartup
  6427.    */
  6428.   init: function at_init() {
  6429.     // get tab context menu
  6430.     var tabbrowser = getBrowser();
  6431.     this.tabContextMenu = document.getAnonymousElementByAttribute(tabbrowser, "anonid", "tabContextMenu");
  6432.  
  6433.     // listen for tab-context menu showing
  6434.     this.tabContextMenu.addEventListener("popupshowing", this.onTabContextMenuLoad, false);
  6435.  
  6436.     // add the tab context menu for undo-close-tab (bz254021)
  6437.     var ssEnabled = true;
  6438.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].
  6439.                      getService(Ci.nsIPrefBranch);
  6440.     try {
  6441.       ssEnabled = prefBranch.getBoolPref("browser.sessionstore.enabled");
  6442.     } catch (ex) {}
  6443.  
  6444.     if (ssEnabled)
  6445.       this._addUndoCloseTabContextMenu();
  6446.   },
  6447.  
  6448.   /**
  6449.    * Add undo-close-tab to tab context menu
  6450.    */
  6451.   _addUndoCloseTabContextMenu: function at_addUndoCloseTabContextMenu() {
  6452.     // get strings 
  6453.     var menuLabel = gNavigatorBundle.getString("tabContext.undoCloseTab");
  6454.     var menuAccessKey = gNavigatorBundle.getString("tabContext.undoCloseTabAccessKey");
  6455.  
  6456.     // create new menu item
  6457.     var undoCloseTabItem = document.createElement("menuitem");
  6458.     undoCloseTabItem.setAttribute("id", "tabContextUndoCloseTab");
  6459.     undoCloseTabItem.setAttribute("label", menuLabel);
  6460.     undoCloseTabItem.setAttribute("accesskey", menuAccessKey);
  6461.     undoCloseTabItem.setAttribute("command", "History:UndoCloseTab");
  6462.  
  6463.     // add to tab context menu
  6464.     var insertPos = this.tabContextMenu.lastChild.previousSibling;
  6465.     this.undoCloseTabMenu = this.tabContextMenu.insertBefore(undoCloseTabItem, insertPos);
  6466.   },
  6467.  
  6468.   onTabContextMenuLoad: function at_onTabContextMenuLoad() {
  6469.     if (AugmentTabs.undoCloseTabMenu) {
  6470.       // only add the menu of there are tabs to restore
  6471.       var ss = Cc["@mozilla.org/browser/sessionstore;1"].
  6472.                getService(Ci.nsISessionStore);
  6473.       AugmentTabs.undoCloseTabMenu.hidden = !(ss.getClosedTabCount(window) > 0);
  6474.     }
  6475.   }
  6476. };
  6477.  
  6478. /**
  6479. * History menu initialization
  6480. */
  6481. //@line 7033 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6482. var HistoryMenu = {};
  6483. //@line 7035 "/cygdrive/K/tinderbuild/src/flock/mozilla/browser/base/content/browser.js"
  6484.  
  6485. HistoryMenu.toggleRecentlyClosedTabs = function PHM_toggleRecentlyClosedTabs() {
  6486.   // enable/disable the Recently Closed Tabs sub menu
  6487.   var undoPopup = document.getElementById("historyUndoPopup");
  6488.  
  6489.   // get closed-tabs from nsSessionStore
  6490.   var ss = Cc["@mozilla.org/browser/sessionstore;1"].
  6491.            getService(Ci.nsISessionStore);
  6492.   // no restorable tabs, so disable menu
  6493.   if (ss.getClosedTabCount(window) == 0)
  6494.     undoPopup.parentNode.setAttribute("disabled", true);
  6495.   else
  6496.     undoPopup.parentNode.removeAttribute("disabled");
  6497. }
  6498.  
  6499. /**
  6500.  * Populate when the history menu is opened
  6501.  */
  6502. HistoryMenu.populateUndoSubmenu = function PHM_populateUndoSubmenu() {
  6503.   var undoPopup = document.getElementById("historyUndoPopup");
  6504.  
  6505.   // remove existing menu items
  6506.   while (undoPopup.hasChildNodes())
  6507.     undoPopup.removeChild(undoPopup.firstChild);
  6508.  
  6509.   // get closed-tabs from nsSessionStore
  6510.   var ss = Cc["@mozilla.org/browser/sessionstore;1"].
  6511.            getService(Ci.nsISessionStore);
  6512.   // no restorable tabs, so make sure menu is disabled, and return
  6513.   if (ss.getClosedTabCount(window) == 0) {
  6514.     undoPopup.parentNode.setAttribute("disabled", true);
  6515.     return;
  6516.   }
  6517.  
  6518.   // enable menu
  6519.   undoPopup.parentNode.removeAttribute("disabled");
  6520.  
  6521.   // populate menu
  6522.   var undoItems = eval("(" + ss.getClosedTabData(window) + ")");
  6523.   for (var i = 0; i < undoItems.length; i++) {
  6524.       var m = undoPopup.appendChild(document.createElement("menuitem"));
  6525.     m.setAttribute("label", undoItems[i].title);
  6526.     m.setAttribute("value", i);
  6527.     m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
  6528.   }
  6529.  
  6530.   // "open in tabs"
  6531.   var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].
  6532.                       getService(Ci.nsIStringBundleService);
  6533.   var stringBundle = bundleService.createBundle("chrome://browser/locale/bookmarks/bookmarks.properties");
  6534.   undoPopup.appendChild(document.createElement("menuseparator"));
  6535.   m = undoPopup.appendChild(document.createElement("menuitem"));
  6536.   m.setAttribute("label", stringBundle.GetStringFromName("cmd_bm_openfolder"));
  6537.   m.setAttribute("accesskey", stringBundle.GetStringFromName("cmd_bm_openfolder_accesskey"));
  6538.   m.addEventListener("command", function() {
  6539.     for (var i = 0; i < undoItems.length; i++)
  6540.       undoCloseTab();
  6541.   }, false);
  6542. }
  6543.  
  6544. /**
  6545.  * Re-open a closed tab.
  6546.  * @param aIndex
  6547.  *        The index of the tab (via nsSessionStore.getClosedTabData)
  6548.  */
  6549. function undoCloseTab(aIndex) {
  6550.   // wallpaper patch to prevent an unnecessary blank tab (bug 343895)
  6551.   var tabbrowser = getBrowser();
  6552.   var blankTabToRemove = null;
  6553.   if (tabbrowser.tabContainer.childNodes.length == 1 &&
  6554.       !gPrefService.getBoolPref("browser.tabs.autoHide") &&
  6555.       tabbrowser.selectedBrowser.sessionHistory.count < 2 &&
  6556.       tabbrowser.selectedBrowser.currentURI.spec == "about:blank" &&
  6557.       !tabbrowser.selectedBrowser.contentDocument.body.hasChildNodes() &&
  6558.       !tabbrowser.selectedTab.hasAttribute("busy"))
  6559.     blankTabToRemove = tabbrowser.selectedTab;
  6560.  
  6561.   var ss = Cc["@mozilla.org/browser/sessionstore;1"].
  6562.            getService(Ci.nsISessionStore);
  6563.   if (ss.getClosedTabCount(window) == 0)
  6564.     return;
  6565.   ss.undoCloseTab(window, aIndex || 0);
  6566.  
  6567.   if (blankTabToRemove)
  6568.     tabbrowser.removeTab(blankTabToRemove);
  6569. }
  6570.  
  6571. /**
  6572.  * Format a URL
  6573.  * eg:
  6574.  * echo formatURL("http://%LOCALE%.amo.mozilla.org/%LOCALE%/%APP%/%VERSION%/");
  6575.  * > http://en-US.amo.mozilla.org/en-US/firefox/3.0a1/
  6576.  *
  6577.  * Currently supported built-ins are LOCALE, APP, and any value from nsIXULAppInfo, uppercased.
  6578.  */
  6579. function formatURL(aFormat, aIsPref) {
  6580.   var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
  6581.   return aIsPref ? formatter.formatURLPref(aFormat) : formatter.formatURL(aFormat);
  6582. }
  6583.